-
Notifications
You must be signed in to change notification settings - Fork 0
/
params.json
1 lines (1 loc) · 14.5 KB
/
params.json
1
{"name":"Bmctigue.github.io","tagline":"","body":"# Unboxing RubyMotion\r\n\r\n## Introduction\r\n\r\nI wrote up a brief description of how I set up my first project using RM in response to a question in the RM Google Group. I had several requests to write up a blog with more details, so here goes. I'm going to give a brief (maybe not so brief) overview of my experience and include some of the lessons I learned. Hopefully this will smooth the way for new RM users.\r\n\r\n## A Brief Bio and a Plug for RM\r\n\r\nI've been coding for a long time, but I don't have a degree in Computer Science. I have a degree in Electrical Engineering. I've never used anything I learned in engineering school, except for the rudimentary skills I learned in programming classes where we ran programs on punch cards (Wow, I'm old). I really enjoy coding, but I consider myself more of an applications developer and I'm mostly self-taught. I don't have any interest in digging deep into the bowels of the framework I'm using. I just want to get my application to work. Thank goodness there are developers who really care that arrays in Objective-C require objects and have to be terminated with a nil, but I'm not one of them. I certainly would not consider myself a \"ninja\" or a \"rockstar\" or some other idiotic term for an exceptional programmer. However, I do code quickly and the code works when it's done. That's where RM really shines. Just coding in ruby elimates an incredible amount of code that doesn't contribute in any way to getting my app done. Don't get me wrong, there are plenty of api gotchas and optimations that require my digging deep, but I don't dig into these unless I need to. When you consider having access to Ruby plus the amazing libraries maintained by the community that add functionality and shortcuts, you will never want to go back to XCode.\r\n\r\nIf you're like me, maybe you just want an array initialized with the number 1. Should be simple, right? \r\n\r\nOld Objective-C - are you kidding me?\r\n\r\n\tNSArray *myArray = [NSArray arrayWithObject:[NSNumber numberWithInt:1]]\r\n\r\nNewer Objective-C - better\r\n\r\n\tNSArray *myArray = @[@1] \r\n\r\nRubyMotion - nice, thank you Matz and Laurent!\r\n\r\n\tmyArray = [1]\r\n\r\nI worked for many years doing Ruby on Rails development, so transitioning from web development to iOS development with RM was a breeze.\r\n\r\n## My First RM Project\r\n\r\nSo I just left my position at Crushpath, what am I going to do now? (This was Dec '12) Of course, I wanted to get started with a new app, but what? I teamed up with a partner who had an idea for a photo sharing app targeted specifically at parents who want to document their kids growing up ([Pixsee](http://appstore.com/pixsee/ \"Pixsee\")). Okay, great. Where do I start? As you know, there are lots of photo sharing apps. Is there some common code to use as a basis?\r\nI had just heard of [Parse](http://parse.com/ \"Parse\") and their backend as a service. Cool, my app doesn't need a website, but we do need to host the data somewhere. [Parse](http://parse.com/ \"Parse\") would save me a ton of development time by not having to create a Rails site to host my data. And as it turns out, [Parse](http://parse.com/ \"Parse\") has an open source example iOS app for photo sharing! \r\n\r\nWith a reasonable size iOS example application in hand and a desire to learn RM quickly, I decided I would just dig in and port the Anypic app to RM. It looked like a daunting amount of typing, but I figured porting a large variety of code to RM would be the quickest way to learn the syntax and my new app could benefit from RM from then on.\r\n\r\n### RM App Structure\r\n\r\nThe first thing I had to decide was what code goes where. You have 3 choices:\r\n\r\n* XCode static library\r\n* Objective-C files stored in the RM Vendor directory\r\n* Straight Ruby files\r\n\r\nI wanted to convert as much of the code to RM as possible, so I decided to put all 3rd party libraries in a new static library and I would convert the rest to Ruby. If you want to convert an application quickly, you might decide to put all your existing code in the static library and then add new functionality with Ruby. You can mix and match. One thing I would caution is if you decide to use a 3rd party library with multiple classes and put it in the static library, you should leave all the files associated with that library in the static library. I'm not sure if it's still an issue, but taking a class out of the static library and putting it in a vendor directory could cause compiling problems with importing header files.\r\n\r\nSo when do I use the vendor directory? Right off the bat the XCode static library goes into a vendor directory. Below is an example Rakefile, which shows the syntax for the static library entry plus other defaults I use. Otherwise, I put Object-C classes that I know I will want to change in a vendor directory. The advantage here is changes to the static library require you to do a rake clean, while changes to the vendor classes don't. Compiling after a clean can take significantly longer than otherwise, because everything has to be recompiled.\r\n\r\nPods don't need to be included in the static library, you should add an entry for each pod in the Rakefile. See the example below. One issue I ran across happens when you remove a pod from the Rakefile. In my experience the resources for the pod aren't removed, so they never go away! If you remove a pod, I would do a rake clean and then remove the Pods directory in the Vendor directory. This way the Pods directory will be clean.\r\n\r\nMove all your resources into the resources directory. This includes all your images and fonts. By default all the resources are put in the top level resources folder, but this can make it difficult to manage the resources. I took advantage of RM's ability to find resources in sub folders if you tell it where to look. You can add a line like this to your Rakefile to organize your resources.\r\n\r\n\tapp.resources_dirs << ['resources/app','resources/backgrounds','resources/buttons','resources/fonts','resources/icons','resources/misc']\r\n\r\nThe example Rakefile also shows how to add information for using different provisioning profiles depending on the environment. I have entries for development and release. When I want to release, I uncomment the correct line depending on whether the release is ad hoc or distribution. I release to both Testflight and Apple and it only takes about 5 minutes now unless I make a mistake like not updating the version number.\r\n\r\nNext, add all frameworks you need to the Rakefile frameworks section.\r\n\r\nLastly, add all your vendor references.\r\n\r\nExample Rakefile:\r\n\r\n\t$:.unshift(\"/Library/RubyMotion/lib\")\r\n\trequire 'motion/project/template/ios'\r\n\trequire 'rubygems'\r\n\trequire 'bubble-wrap/core'\r\n\trequire 'sugarcube'\r\n\trequire 'bundler'\r\n\trequire 'motion-cocoapods'\r\n\r\n\tMotion::Project::App.setup do |app|\r\n\t # Use `rake config' to see complete project settings.\r\n\t app.name = '########'\r\n\t app.identifier = '########'\r\n\t app.version = '########'\r\n\t app.sdk_version = '6.1'\r\n\t app.deployment_target = '6.0'\r\n\t app.prerendered_icon = true\r\n\t app.interface_orientations = [:portrait]\r\n\t app.seed_id = '########'\r\n\t app.entitlements['application-identifier'] = app.seed_id + '.' + app.identifier\r\n\t app.entitlements['keychain-access-groups'] = [app.seed_id + '.*']\r\n\r\n\t app.development do\r\n\t app.codesign_certificate = '########'\r\n\t app.provisioning_profile = '########'\r\n\t app.entitlements['aps-environment'] = 'development'\r\n\t app.entitlements['get-task-allow'] = true\r\n\t end\r\n\r\n\t app.release do\r\n\t app.codesign_certificate = '########'\r\n\t # distribution profile\r\n\t # app.provisioning_profile = '########'\r\n\t # ad hoc profile\r\n\t app.provisioning_profile = '########'\r\n\t app.entitlements['aps-environment'] = 'production'\r\n\t app.entitlements['get-task-allow'] = false\r\n\t end\r\n\r\n\t app.pods do\r\n\t pod 'SomePod', '~> 0.0.1'\r\n\t end\r\n\r\n\t app.libs += ['/usr/lib/libz.dylib', '/usr/lib/libsqlite3.dylib']\r\n\t app.info_plist['CFBundleShortVersionString'] = '1.2.4'\r\n\t app.info_plist['UIAppFonts'] = ['FontAwesome.otf']\r\n\r\n\t app.frameworks += ['UIKit']\r\n\t app.vendor_project('vendor/Parse.framework', :static, :products => ['Parse'], :headers_dir => 'Headers')\r\n\t app.vendor_project('vendor/Pixsee', :xcode, :xcodeproj => 'Pixsee.xcodeproj', :target => 'Pixsee', :products => ['libPixsee.a'])\r\n\tend\r\n\r\n### 2 Weeks of Typing (mostly copy and pasting)\r\n\r\nUpdate - 8/20/13: There's a plugin for Sublime Text 2/3 that let's you convert Objective-C to RubyMotion! So you may be able to skip the following advice for converting by hand. Thanks to Ivan Acosta-Rubio for the heads up and link (@ivanacostarubio). You can find the plugin here: [SublimeObjC2RubyMotion](https://github.com/kyamaguchi/SublimeObjC2RubyMotion/ \"SublimeObjC2RubyMotion\")\r\n\r\nOk, so now I'm ready to port over all the classes to RM. It wasn't exciting, but I took 2 weeks over Christmas to get it done. I use Sublime Text for my development. Fortunately, there are common code blocks you can replace over and over. In Sublime Text, command-d and replace are going to be your best friends. \r\n\r\nLet's start with the header files. Oh, wait, that's right! There aren't any!!\r\n\r\nThen let's convert the implementation files. Generally, I would create a new Ruby class and copy and paste the guts of the Objective-C class. The following are a few examples of the very common blocks of Objective-C you can remove or replace with RM equivalents.\r\n\r\n1. Remove all \";\"\r\n2. Remove all \"{\" where appropriate(i.e not opening a hash)\r\n3. Replace all \"}\" with \"end\" where appropriate (i.e. not closing a hash)\r\n4. Replace all \"else if\" with \"elsif\"\r\n5. Replace \"[object message]\" with \"object.message\"\r\n6. Replace blocks \"^{ }\" with \"lambda {}\" (or equivalent, include parameters if necessary)\r\n7. Replace method return types, i.e. replace \"- (void)\" with \"def\"\r\n8. Method declations - RM syntax is quite close to Objective-C:\r\n\r\nReplace:\r\n\r\n\t- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {\r\n\t}\r\n\r\nWith:\r\n\r\n \tdef touchesBegan(touches, withEvent:event)\r\n\tend\r\n\r\nNotice all the parameters are separated with commas and there are no type declarations.\r\n\r\nAlso, you need to replace all lowercase first letters in constants with uppercase. Constants in Ruby are uppercase. This seems to trip up everyone at the beginning. I like to create a constants module where I can easily update the values. Import the constants module where you need access to the constants:\r\n\r\n\tmodule MyConstants\r\n\t KApplicationName = 'Pixsee'\r\n\t KTestFlightId = '########'\r\n\tend\r\n\r\nI know there are all sorts of opinions on code organization, but I like to refactor non-essential code to a separate file where I can find it easily. For example, I take advantage of Ruby Modules to separate out button code from view controllers so I don't clutter up the main code. I just put the button definitions and actions into a separate module and then include the module in the view controller.\r\n\r\nCategories from Objective-C are dead simple to create. Just create a class with the same name as the class you are extending and add the new methods. Done. I generally put files like this in a lib directory under the main app directory.\r\n\r\nFinally, you may have Interface Builder files you want to use in your project. I didn't it in this project, but I have in subsequent projects. You'll want to check out [IB](https://github.com/yury/ib/ \"IB\"), which makes it very simple to use your xib files with the syntax you're used to. You can open Interface Builder from RM, so you can maintain your xib files normally.\r\n\r\n## Stuff I always Use\r\n\r\n### BubbleWrap and SugarCube - Don't leave home without them\r\n\r\nTo me, this is RM's secret sauce. These two libraries have a huge number of coding shortcuts. You will certainly find a few that you use over and over again. Let me give you an example. I like to create a theme class that defines a four color palette. I use the palette to give my app a pleasant look with colors that provide good contrast until I get to the stage where I need a real graphic designer. The following defines a simple theme class with a Facebook blue color palette:\r\n\r\n\tclass MyTheme\r\n\t @light_color = [218,228,240].uicolor\r\n\t @very_light_color = [237,237,245].uicolor\r\n\t @dark_color = [53,93,152].uicolor\r\n\t @very_dark_color = [38,65,108].uicolor\r\n\t @default_text_color = :white.uicolor\r\n\t @default_font_name = 'FontAwesome'\r\n\t @default_font_size = 16\r\n\r\n\t class << self\r\n\t attr_reader :light_color,\r\n\t :very_light_color,\r\n\t :dark_color,\r\n\t :very_dark_color,\r\n\t :default_text_color,\r\n\t :default_font_name,\r\n\t :default_font_size\r\n\t end\r\n\tend\r\n\r\nThen I can use:\r\n\r\n\tmyView.backgroundColor = MyTheme.very_dark_color\r\n\r\nHow about specifying a color with '#FF8A19'.to_color or :clear.uicolor? You might review [BubbleWrap](http://bubblewrap.io/ \"BubbleWrap\") and [SugarCube](https://github.com/rubymotion/sugarcube/ \"SugarCube\") to see everything they provide.\r\n\r\n### FontAwesome - an awesome font\r\n[FontAwesome](http://fortawesome.github.io/Font-Awesome/ \"FontAwesome\") provides an incredible number of icons you can include in text strings. We use the icons liberally throughout ([Pixsee](http://appstore.com/pixsee/ \"Pixsee\")) to spice up text, especially in natural places like menu tableviews.\r\n\r\n## Conclusion\r\n\r\nI went through this exercise over 7 months ago, so I may have missed a few of the hurdles I had to jump to get a working app. I know this may a bit simplistic for the sophisticated RM audience, but I hope this is useful if you are getting your feet wet with a new or ported app.\r\n\r\nThere is way more available than I can review here. Make sure you review everything on the developer page. I would also review all the cool RM wrappers and libraries. There is probably something there that will make your life much easier.\r\n\r\nDon't forget to thank the RM team for making coding fun again! Or, I'm sure they wouldn't mind you buying a license and skipping the thank you. 8>)","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."}