App Delegate

Let's talk about delegation pattern first. Delegation means that some object instead of dealing with some task, delagates it to some other object.

All code below does not need memorizing. It is just an example of how delegation works. We just need to understand the idea.

For example, you want a user to select a photo from his media library. You create ImagePicker object, and you show it to the user:

        # this is not a real code
        picker = ImagePicker.new
        picker.show
      
ImagePicker is a third-party library, written by other people. It can only help the user to select some images. However ImagePicker does not know what to do with those selected images - it delegates this to us. It means we need to specify who will process our images:
        picker.delegate = current_screen
      
When the user selects some images, ImagePicker object will call a delegate and will pass it selected images. Delegate's job here is to process them. Image picker would say to delegate: "there were some images selected. Please figure out what to do with them". In our example, to make delegate work, we would need to create a method that would accept this images. Method names are always specified in a delegator (an object that asks for a delegate). You can't figure out a name by yourself - delegator will call a specified method only. It would look similar to this:
        # this is not a real code
        picker = ImagePicker.new
        picker.show
        picker.delegate = self

        # this method will be called automatically by ImagePicker object,
        # when images will be selected:
        def images_selected(images, error: error)
          if error
            # show some error
          else
            # save images
          end
        end
      

Another example is application loading: user tapped on a Springboard on your app's icon, and iOS started to load it. When your app has been launched, the delegate will be called. iOS would say to delegate: "Hey, I just loaded an app, what are you going to do next?". Usually, we start loading application screens.

One more example: tables. We have a table with ten cells in it. For example, this is a table with some of the user's contacts. When we create a table, we tell it that our current object will be a delegate for this table view:

        @table = UITableView.new
        @table.delegate = self
      
Then, when user will tap on a cell, table will call a method:
        def tableView(table, didSelectRowAtIndexPath: index)
          # you can process a tap here
        end
      
Inside of this method, we can figure out which contact has been selected, and open a new screen with this contact's info.

In other words, delegates are made to deal with results of some actions. The delegate will be called when images selected, when some file has been downloaded, when the app has been loaded, etc. Delegate object will decide what to do next - show some new screens, show an error, etc.

When you create a new iOS project, you will find an Application Delegate file there. In Rubymotion it is a /app/app_delegate.rb file. App Delegate is the main delegate that is called when the app is loaded or closed. It will be called when push notifications arrive, or when memory warning received, and in lots of other cases.

All available delegate methods can be found at Apple's docs: App Delegate Docs. For now, we are interested in

application:didFinishLaunchingWithOptions:

If you open app_delegate in superapp, you will see that this method is already there. This is the main method that called right when the app has been launched, and it waits for our instructions. Rubymotion guys decided to add one screen for us already.

At the first glance code in the app_delegate may look scary. This is because it is a plain Objective-C converted to Ruby.

We are going to learn how to make apps in Ruby-way, and not in Objective-C way. To do it, we need to install some gems first.

To start, let's add ProMotion gem to our Gemfile. ProMotion is an awesome library that helps us to write real Ruby code. We will use their gem to create Screens (in Objective-C you would call them UIViewControllers).

To add ProMotion to the app, just open your Gemfile, and add next line:

        gem 'ProMotion'
      
Then install it from your terminal with bundle install.

And now we can make our app delegate prettier. ProMotion developers upgraded default AppDelegate class a little bit, and we are going to use it as a base for our App Delegate. Let's remove all code inside the

application:didFinishLaunchingWithOptions:
method so that file would look like this:
        class AppDelegate
          def application(application, didFinishLaunchingWithOptions:launchOptions)
            true
          end
        end
      
Try to launch the app now with rake. You will see a boring black screen now.

Now we are going to replace the Objective-C-like code with a Ruby code. I hope you still remember what Inheritance is because we are going to inherit our AppDelegate from ProMotion's PM::Delegate class. We will also replace

application:didFinishLaunchingWithOptions:
with Ruby-like
on_load(app, options)
method. This is how your app_delegate.rb should look like now:
        class AppDelegate < PM::Delegate
          def on_load(app, options={})
          end
        end
      

ProMotion's job here is to replace - application:didFinishLaunchingWithOptions: with the on_load method - the last one is easier to remember, to read, and to use. Also, plain Objective-C method would require us always return true, to make iOS know that everything is fine, and the app has been launched.

If you are interested how does it works: it is very easy. We made our AppDelegate class derive from PM::Delegate, which has this method implemented: - application:didFinishLaunchingWithOptions:. When it is time, this method has been called, and it tries to call the on_load method. If you are interested, here is ProMotion's source code that does just this: PM::Delegate

To know correct delegate names for Promotion's App Delegate, you can always visit their docs: ProMotion Docs on App Delegate

Summary

In this chapter, we've learned about Delegation Pattern. It has delegator - the object that is going to do some action for us. And delegate - the object that will be called when delegator will finish its task. Delegator will ask the delegate to process the result.

App Delegate is a place where you can customize application's behavior when it opens, closes, receives memory warnings, etc. This is the main file that starts your application.

For now, let's continue to the next chapter to learn about Rubymotion console.

Book Index | Next