News

 
  • 15 May

    Introducing ProMotion, a Full-Featured RubyMotion Application Framework

    (This is a guest post from Jamon Holmgren, creator and maintainer of ProMotion)

    Last August I started working on a new RubyMotion app. I quickly realized that one of UIKit’s most frequent pain points is working with UINavigationControllers, UITabBarControllers, and UIViewControllers — it just took too many lines of code to move around in my app. That led to the idea behind ProMotion: abstracting the screen and navigation handling in a Ruby-like way.

    It has been a great experience building it and I’m going to show you how ProMotion could make your next iOS project a lot easier (with lots of code examples!). The source is also available on GitHub.

    Screens: Ruby-like UIViewControllers

    ProMotion subclasses UIViewController and UITableViewController to provide a ton of new functionality and abstraction and calls them ProMotion::Screen. (You can also use ProMotion with Formotion or your own UIViewController).

    Note: from now on I’ll refer to ProMotion by its shortcut alias, PM.

    class HomeScreen < PM::Screen
      title "Home"
    end
    

    Pretty simple. What about viewWillAppear:animated and other Obj-C methods? We implement simpler versions of those for your use:

    def on_init
    # Fires right after the screen is initialized
    end
    
    def on_load
    # Fires just before a screen is added to a view for the first time.
    end
    
    def will_appear
    # Fires every time the screen will appear
    end
    
    def on_appear
    # Fires just after the screen appears somewhere (after animations are complete)
    end
    
    def will_disappear
    # Fires just before the screen will disappear
    end
    
    def on_disappear
    # Fires after the screen is fully hidden
    end
    
    Invisible UINavigationControllers

    When you create a screen you can pass in attributes. One of these is nav_bar: true which creates a UINavigationController and pushes the screen onto it. You don’t have to manage the navigation controller at all.

    open HomeScreen.new(nav_bar: true)
    

    Within that screen you can open other screens and they’ll be pushed onto the UINavigationController automatically.

    open SecondaryScreen
    

    If you pass in a class instead of an instance, ProMotion will instantiate it for you.

    Easy TabBarControllers

    Opening and managing a UITabBarController is a pain in Objective-C. ProMotion makes it very simple and natural.

    class AppDelegate < PM::Delegate
      def on_load(app, options)
        open_tab_bar HomeScreen, AboutScreen, ContactScreen, HelpScreen
      end
    end
    
    # in app/screens/home_screen.rb
    
    class HomeScreen < PM::Screen
      def open_another_tab
        # Switches to the AboutScreen created above if its tab title is “About”.
        open_tab “About”
      end
    
      def open_new_screen_in_another_tab
        # Programmatically switches to the HelpScreen
        # and pushes the SecondaryScreen onto its UINavigationController.
        open SecondaryScreen, in_tab: “Help”
      end
    end
    
    Smart SplitViewControllers

    Split view controllers are as easy as tab bars.

    open_split_screen MenuScreen, DetailScreen
    

    open split screen

    From the left-hand part of the split screen it’s easy to open a child screen in the right. Just add in_detail: true to the open command:

    open SomeDetailScreen, in_detail: true
    

    This is ignored if there isn’t a split screen so it’s ideal for use in universal apps.

    Effortless Table Screens

    You can easily build list views (“tables”) in ProMotion. Formotion is excellent for building forms, but sometimes you just want a menu or list of information. That’s where ProMotion’s built-in TableScreen works well.

    class HelpScreen < PM::GroupedTableScreen
      title "Help"
    
      def table_data
        @help_table_data ||= [{
          title: "Get Help",
          cells: [{
            title: "Email us", action: :email_us
          }]
        }]
      end
    
      def email_us
        mailto_link = NSURL.URLWithString("mailto:jamon@clearsightstudio.com")
        UIApplication.sharedApplication.openURL(mailto_link)
      end
    end
    

    When the Email us cell is tapped, ProMotion fires the email_us method.

    table screen

    For plain tables, you can add searchable and refreshable easily:

    class StatesScreen < PM::TableScreen
      title “States”
      searchable
      refreshable
    
      def table_data
        # list of states
      end
    
      def on_refresh
        # refresh your data here, usually async
        some_async_call do
          # update your data
          stop_refreshing
          update_table_data
        end
      end
    end
    

    searchable, refreshable list of states

    Styling with Style

    Everybody has their favorite iOS styling system and ProMotion works beautifully with all of them. Pixate, NUI, and of course RubyMotion’s Teacup are all very good choices.

    For those who want a simple, Teacup-lite styling system, ProMotion comes with one built-in.

    set_attributes self.view,
      background_color: UIColor.grayColor
    
    add UILabel.alloc.initWithFrame([[10, 10], [300, 45]]),
      text: “Welcome to ProMotion!”,
      resize: [ :left, :right, :top ],
      background_color: UIColor.clearColor,
      text_color: UIColor.whiteColor,
      shadow_color: UIColor.blackColor,
      number_of_lines: 0,
      text_alignment: UITextAlignmentCenter,
      font: UIFont.boldSystemFontOfSize(18.0)
    

    This UILabel is added to the view and all the attributes are set. Snake case is converted to camel case automatically when appropriate. There are also some nice helpers like the resize setting for UIViewAutoresizingMasks.

    image

    Perfect for Production

    ProMotion is already being used in production apps around the world and is becoming quite stable. It’s likely that version 1.0 will be coming soon without major changes to the API.

    Without RubyMotion, it’s very unlikely that a system like ProMotion would exist. There’s nothing like it in the Objective-C world and the community is a lot different there. It’s a testament to the RubyMotion community as well as Laurent and his team for making this possible.

    This is just an intro to ProMotion — head over to the GitHub repo to learn more. I hope you take a look at it for your next project!

    Jamon Holmgren (@jamonholmgren) is the owner of ClearSight Studio, a mobile app and web development studio located near Portland, OR.

 
 

Want to stay in touch?

Follow us on Twitter