The Secret Life Of App.alert()
I was a bit stuck this week on what to write about, then I got this from @markrickert
@FluffyJack I'm always digging into source for App.alert(). It's so powerful, but there's barely any documentation for it on bubblewrap.io
When I actually dived into the source code of bubblewrap's UIAlertView, I was actually surprised by how much more was in there than I knew about.
Also this got me thinking, if you're struggling with something or have something you'd like me to write about, just tweet me.
This is the login and password alert (UIAlertViewStyleLoginAndPasswordInput) which is a great alternative to creating a whole UI yourself for your users to login to your app.
My favourite thing about it, how little code it takes.
alert = BW::UIAlertView.login_and_password_input(title: 'Login')
alert.show
Done. That's displaying it sorted. Beautiful! Ok, that's really not that helpful. We can't do much with that. Lets try again.
alert = BW::UIAlertView.login_and_password_input(title: 'Login') do |a|
APIExample.authorize(a.login_text_field.text, a.password_text_field.text) unless a.clicked_button.cancel?
end
alert.show
Now that's the kind of Rubyness I like to see.
You can do several kinds of 'alerts'. There is the plain one you're used to with a title, message, and some buttons. Then you can also use one of 3 different kinds of input ones like the login one I showed you. A normal text input, 'secure' text input (password looking field), and the login and password alert. This gives you a really great range of input and feedback options without the need of creating a UI for certain small tasks. I also must say, they input related ones look A LOT better in iOS 7 than iOS 6!
If you're looking to just quickly put something on the screen though...
App.alert('Oops!', message: 'You forgot an email')
Nice and simple. Any options you can pass to BW::UIAlertView
can be passed to App.alert
, like buttons. You can also use a block to handle it being closed too.
Alrighty, I reckon you're probably getting the basic gist of what you can do with App.alert
and BW::UIAlertView
now, so here is some 'docs' I've written up for it. Enjoy!
BW::UIAlertView
First step as with any part of bubblewrap is of course adding the gem.
gem 'bubble-wrap'
Or if you're not using Bundler, just run gem install bubble-wrap
then in your Rakefile add one of these.
# All of bubblewrap
require 'bubble-wrap'
# Or just the core and UI stuff
require 'bubble-wrap/core'
require 'bubble-wrap/ui'
Now you're ready to go with bubblewrap.
Stock standard BW::UIAlertView
Though BW::UIAlertView has a lot of methods for creating different kinds of alerts, all of them are just creating a new BW::UIAlertView, which you can do with:
BW::UIAlertView.new.show
That's going to do basically nothing until you give it some details of what you want to show in it and what buttons there will be, so we'll take a look at some of the options.
options[:title]
By passing this along to BW::UIAlertView.new
you can set the larger bolder text you'll sometimes see in alerts.
BW::UIAlertView.new({
title: 'My Title'
}).show
You might want to show a bit more information though, which leads us to...
options[:message]
This is the option for the smaller longer text you see in other alerts, and is where you can give the user a bit more detail about what you're alerting them of.
BW::UIAlertView.new({
title: 'My Title',
message: 'Welcome to my awesome little alert view! Have an nice day!'
}).show
But you need to give your user a way to close the alert.
options[:buttons]
You can provide all the buttons you'd like to show the user, though I don't recommend more than a cancel/ok button, and an action button, otherwise just the cancel/ok button.
BW::UIAlertView.new({
title: 'My Title',
message: 'Welcome to my awesome little alert view! Have an nice day!',
buttons: ['OK', 'Learn More']
}).show
We'll look at one more option before we start actually doing something with our alerts.
options[:cancelbuttonindex]
This option lets you set which is the 'cancel' button out of your buttons. It's usually the button that just closes the alert and does nothing as a reaction like "OK", "Cancel", or "No". It's almost always 0 unless you want to confuse your users with putting the non-destructive button in a place they're not used to (hint: don't do that). Also if you only have the one button, no need to worry about this.
BW::UIAlertView.new({
title: 'My Title',
message: 'Welcome to my awesome little alert view! Have an nice day!',
buttons: ['OK', 'Learn More'],
cancel_button_index: 0
}).show
Now we're ready to actually start handling the interaction!
BW::UIAlertView callbacks and it's block
BW::UIAlertView lets you give it a block, this will just assign that block to the on_click
callback.
BW::UIAlertView.new({
title: 'My Title',
message: 'Welcome to my awesome little alert view! Have an nice day!',
buttons: ['OK', 'Learn More'],
cancel_button_index: 0
}) do |alert|
if alert.clicked_button.cancel?
puts 'Canceled'
else
puts 'They want more!'
end
end.show
Or the alternative to this is to pass the callback in as one of the options.
callback = lambda do |alert|
if alert.clicked_button.cancel?
puts 'Canceled'
else
puts 'They want more!'
end
end
BW::UIAlertView.new({
title: 'My Title',
message: 'Welcome to my awesome little alert view! Have an nice day!',
buttons: ['OK', 'Learn More'],
cancel_button_index: 0,
on_click: callback
}).show
Just a matter of preference really.
There is also several other callback options, which are just abstractions for the UIAlertViewDelegate.
- :will_present
- :did_present
- :onsystemcancel
- :enablefirstother_button?
- :on_click
- :will_dismiss
- :did_dismiss
Which are all fairly self explanatory, but I've linked each to the respective UIAlertViewDelegate documentation.
UIAlertView Styles
There are 4 options for which style of UIAlertView you would like to use. The first is the default, and is rightly called :default
, but you also have access to :plain_text_input
, :secure_text_input
, and :login_and_password_input
.
You can set which style you would like using the :style
option when creating your BW::UIAlertView
.
BW::UIAlertView.new({
title: 'Your Name',
message: 'Please enter your Full Name',
buttons: ['No', 'Save'],
cancel_button_index: 0,
style: :plain_text_input
}).show
:plain_text_input
will give you a single text field, :secure_text_input
provides you with a password style input field, and :login_and_password_input
gives one of each.
You can also get and set the style using the style
attribute, just do it before you show
it.
alert = BW::UIAlertView.new
alert.style = :secure_text_input
puts alert.style
alert.show
Accessing the input
These 3 other styles aren't very handy unless you can actually get to what the user entered, so bubblewrap gives you 4 method to access that information.
# For the :plain_text_input
alert.plain_text_field.text
# For the :secure_text_input
alert.secure_text_field.text
# For the :login_and_password_input
alert.login_text_field.text
alert.password_text_field.text
Use these in your callbacks to get access to what the user entered. This is also possible with the cancel_button_index
.
Sensible defaults
That's everything that BW::UIAlertView can do, but it goes a bit further in helping you do some of these things a bit easier by providing you with a 4 creation methods that give you some sensible defaults for the 4 kinds of alerts.
# The default - default style and an 'OK' button
BW::UIAlertView.default(options, &block)
# Plain text input - plain text input style, 'Cancel' and 'OK' buttons, and cancel index of 0
BW::UIAlertView.plain_text_input(options, &block)
# Secure text input - secure text input style, 'Cancel' and 'OK' buttons, and cancel index of 0
BW::UIAlertView.secure_text_input(options, &block)
# Login and password input - login and password input style, 'Cancel' and 'Log in' buttons, and cancel index of 0
BW::UIAlertView.plain_text_input(options, &block)
Very sensible defaults indeed. You can pass all of the same options that you can to BW::UIAlertView.new
.
App.alert()
Bubblewrap also gives you an even more convenient option if all you want to do is quickly display an alert. App.alert()
will create and show a BW::UIAlertView.default
, with one "OK" button, and a cancel index of 0.
There is several ways to use it.
# Super basic
App.alert('My Title')
# With some options
App.alert('My Title', message: 'My Message')
# With different cancel text
App.alert('My Title', 'Cancel')
# Cancel text and options
App.alert('My Title', 'Cancel', message: 'My Message')
# And if you want to change attributes between creating it and showing it, pass a block
App.alert('Login', buttons: ['Cancel', 'Login']) do |alert|
alert.style = :login_and_password_input
end
Keep in mind that the block works differently with App.alert()
than BW::UIAlertView.new
. The block for App.alert()
lets you customise the alert before show
is called, instead of being a shortcut for an :on_click
callback. So in this case, if you want a callback, you'll need to use the syntax I showed you earlier.
That's all!
That's it for BW::UIAlertView
and App.alert()
.
Keep in mind this BW::UIAlertView
is basically just providing a more convenient syntax for working with alerts, all this is possible with the standard UIAlertView
with a bit more code (not too much more). So if you don't want to use bubblewrap, you can still enjoy all of this, you just need to read up on UIAlertView.