Monthly Archives: July 2014

Issue #38

Did you know that constant lookups are slow in Ruby?

Laurent and I were having a conversation one day about things in Ruby (and RubyMotion) that were slower than one might expect. The big one that popped out at me was that Constant lookups are slow.

That was crazy to me, as I assume that FOO = 'Bar' is the fasted way. It turns out that Ruby’s rules for constant lookup are so complicated that only the MRI implements all of them. Because of this, the process is slow.

The fastest thing you can use to store ‘Bar’ is to use @foo = 'Bar'.

It’s all relative of course and “slow” in this case is still very fast compared to most of our application code. However, if you are in a tight loop and you need the highest performance possible it’s good to know about. Also, Laurent said he caches the constants in the RM runtime to help with this problem.

Method invocation (calling a method) is also one of the slower low level things to do. So for maximum performance, you can inline them into one method.

image


If you missed the last issue, you can find it here: issue #37.

Happy coding, Todd Werth (@twerth)

Articles, News, New Gems, and Blog Posts


July 28th, 2014 | screencast | by Jack Watson-Hamblin
MotionInMotion – Episode 35 – Tab Bar Controllers And How To Customise Them

July 24th, 2014 | training | by Colin T.A. Gray
http://training.rubymotion.com/

July 22th, 2014 | book | by Clay Allsopp
Updated to iOS7 and RM 2.0 – RubyMotion iOS Development with Ruby

July 16th, 2014 | video | by Gant Laborde
Motion Meetup – July 2014 with Colin T.A. Gray

Hidden Gem by Gant Laborde


My text fields aren’t selectable!? Tapping them doesn’t make them becomeFirstResponder!? What am I doing wrong!?

When adding a group of interactive fields to a view, people like to add them grouped, by superview. Often times, in RMQ you’ll see something similar to this:

rmq.append(UIView, :form).tap do |form|
  form.append(UITextField, :some_input1).get.becomeFirstResponder
  form.append(UITextField, :some_input2)
  form.append(UITextField, :some_input3)
  form.append(UITextField, :some_input4)
end

The same can be done by a bunch of addSubview(input) calls, for non-rmq.

QUESTION: Why would it be that you can’t select a text field with a tap?

  • Enable User Interaction? Nope, each subview has their own event queue.
  • Animating? Nope. Though user interaction is disabled on animation (unless UIViewAnimationOptionAllowUserInteraction is set), and that code isn’t animating.

ANSWER:

You can lay everything out, but it’s very important that you make sure the superview (:form in this case) is the right size. If not, then your text fields will be visible but not selectable. In these situations, it’s best to set a holder UIView with clipsToBounds = true to avoid a form growing beyond it’s size, or simply being misaligned down the road.

Sponsor


My company InfiniteRed sponsors this newsletter by allowing me the time to work on it every week and hosting everything.

Contact us if you ever need help working on a project, mentoring, or other development services . We specialize in RubyMotion and have an awesome team.

image

One more thing


This is useful for Objective-C documentation and sample code. It’s not 100% perfect, but I use this a lot to get started.

Objective-C to RubyMotion Converter


If you have any tips, blog posts, or want to sponsor this newsletter, please send emails to todd@infinitered.com

Issue #37

ProMotion Tip of the week

I’d like to welcome Jamon to the Dispatch. He created ProMotion and wrote this week’s ProMotion tip. Let me know what you think, maybe we can persuade him to write a tip every so often.


If you missed the last issue, you can find it here: issue #36.

Happy coding, Todd Werth (@twerth)

Articles, News, New Gems, and Blog Posts


July 24th, 2014 | blog post | by Mirko Stocker
RubyMotion Announces Android Support

July 21st, 2014 | blog post | by Gant Laborde
Custom Controller Transitions in RubyMotion

July 21st, 2014 | screencast | by Jack Watson-Hamblin
MotionInMotion – Episode 34 – Toolbars

July 18th, 2014 | video | by Arkency
Rubymotion App with ProMotion gem

July 18th, 2014 | blog post | by Thomas Mayfield
Setting Up a RubyMotion Project on Travis CI

ProMotion Tip of the Week by Jamon Holmgren


Passing data between screens

When opening and closing screens, you often want to pass data between them. ProMotion has a simple built-in way to do this.

First, define a writable property on your new screen:

class NewScreen < PM::Screen
  attr_accessor :my_data
  # ...
end

Then, when instantiating the new screen, set the data as part of your new call.

open NewScreen.new(my_data: @my_data_here)

Within the NewScreen instance, you’ll now have access to self.my_data which is a strong reference to the object @my_data_here.

When you’re done with a screen and want to close it, you may want to pass some data or information (such as success or failure) back to the parent screen. Just add the info to your close call like this:

# in ChildScreen
def some_method
  close saved: true
end

…and then implement the on_return action in your parent screen.

# in ParentScreen
def on_return(args={})
  puts args[:saved] # => true
end

I use these two features all the time for simple, effective communication between screens.

Hidden Gem by Gant Laborde


Today’s Hidden Gem is a quick Ruby trick. You are likely familiar with Array#uniq.

uniq: provides a unique set of a given array (Also popular in Active Record queries in Rails, under the same concept). So [1, 1, 2, 3, 5].uniq returns [1, 2, 3, 5].

Quick Trick: Combining arrays and preserving the uniqueness happens often. Your first thoughts for combining Array a and b might be (a + b).uniq but did you know you can just use the ruby OR for the same result?

a = [1, 2]
b = [2, 3]
c = [3, 4, 5]

x = a | b | c
# => [1, 2, 3, 4, 5]

RubyMotion News


RubyMotion 2.31

  • The iOS 8.0 and OS X 10.10 versions of the runtime have been recompiled
    with Xcode 6 Beta 4.
  • Fixed a regression where a crash would happen when calling methods with
    variadic arguments.
  • Fixed a bug where Unicode characters outside the BMP of a String object
    would not be properly extracted when passed to an Objective-C API.
  • Fixed a bug where a “not precompiled” error would happen when calling the
    NSURLSessionDownloadTask#cancelByProducingResumeData method.
  • Fixed a bug where a crash would happen when trying to override a method that
    has `MKOverlayRenderer’ arguments (ex. #drawMapRect:zoomScale:inContext:).
  • Fixed a bug where trying to retrieve a value from a Hash object using a
    key wrapped as a WeakRef would not work as expected.
  • [iOS] Fixed a bug where ^C would not terminate the `rake debug=1′ debugging
    session immediately.
  • [iOS] Fixed a bug where custom debug commands (ex. pro, pri) would not
    work in a remote/device debugging session.
  • [iOS] Fixed a bug which user-defined debug commands would not be loaded
    in a remote/device debugging session.

Sponsor


My company InfiniteRed sponsors this newsletter by allowing me the time to work on it every week and hosting everything.

Contact us if you ever need help working on a project, mentoring, or other development services . We specialize in RubyMotion and have an awesome team.

Wat!


Halt and Catch Fire: finally a show about programmers and hardware engineers that is realistic, smart, mature, and highly entertaining (although overly dramatic, of course, no one wants to just watch us type all day).


If you have any tips, blog posts, or want to sponsor this newsletter, please send emails to todd@infinitered.com

Issue #36

New logo

I was tired of “real work” Friday night, so like any popular guy with too many fiends, I spent my Friday night making a new logo for the Dispatch. I really enjoyed making it, I hope you like it.


If you missed the last issue, you can find it here: issue #35.

Happy coding, Todd Werth (@twerth)

Announcements


Motion Meetup today at 3PM PST

Join us here.

ChicagoRubyMotion meet-up

Meets every 2nd Tuesday.

Articles, News, New Gems, and Blog Posts


July 16th, 2014 | new site | by Clay Allsopp
Motion Toolbox – A collection of RubyMotion libraries and wrappers

July 15th, 2014 | new gem | by Erwin Boskma
motion_ocean – A RubyMotion library for version 2 of the DigitalOcean API.

July 15th, 2014 | gem release | by Clay Allsopp
motion-screenspecs – Test your RubyMotion app using screenshot comparison

July 15th, 2014 | video | by Multiple
RubyMotion Sydney July meetup videos

July 14th, 2014 | screencast | by Jack Watson-Hamblin
MotionInMotion – Episode 33 – Roll Your Own API Client Using NSURLSession

July 13th, 2014 | slides | by Eiji Iwazawa
Japanese – RubyMotion, a comfortable place

July 11th, 2014 | gem release | by Clay Allsopp
1.7.0 – bubblewrap

July 11th, 2014 | new gem | by Mark Rickert
motion_print – A RubyMotion pretty printer

July 10th, 2014 | blog post | by Thomas Mayfield
Testing a RubyMotion App With a Rails Backend

July 10th, 2014 | blog post | by Jack Watson-Hamblin
The Bullied Who Have Become The Bullies

July 10th, 2014 | gem release | by Colin T.A. Gray
2.0.0 Sugarcube

July 9th, 2014 | gem release | by Colin T.A. Gray
1.1.9 – motion-wiretap – A wrapper for KVO, gestures, UIControl events, and procs. Inspired by ReactiveCocoa.

July 9th, 2014 | gem release | by Clay Allsopp
0.1.0 – motion-screenshots – Automatic screenshots for your RubyMotion apps

Hidden Gem by Gant Laborde of Iconoclast Labs


For those of us coming from Rails, we do enjoy Object#try. It allows us a friendly way to attempt methods without having to check if the object responds to designated method first.

Of course you can gain this functionality by bringing in the motion-support gem (ActiveSupport methods that make sense in RubyMotion). But in some cases I even prefer the simply inline rescue. Especially, if we don’t want to completely sweep the failed method under the rug.

Object.method_will_miss('it will') rescue nil

This will still raise an undefined method in RubyMotion, but rather than bombing out with the exception, it will return our rescued nil. This methodology gives you the app security and at the same time it helps you find bad data issues.

NOTE: Behavior of undefined methods differ on versions/flavors of Ruby.

From the Archives

Because it’s easier to copy and paste than to write


RubyMotion Views != Rails Views

I think this causes a lot of confusion. Some may disagree with me, but think of RubyMotion controllers as Rails’ controllers + Rails’ views, and think of RubyMotion’s views as Rails’ partials.

In some other development environments, a UIView would be called a control, and a UIViewController would be a screen.

This is overly simplified, but I think it gives you a better mental model of what they are actually are.

Sponsor


My company InfiniteRed sponsors this newsletter by allowing me the time to work on it every week and hosting everything.

Contact us if you ever need help working on a project, mentoring, or other development services . We specialize in RubyMotion and have an awesome team.

Wat!


Apple and IBM?

image


If you have any tips, blog posts, or want to sponsor this newsletter, please send emails to todd@infinitered.com

Issue #35

  • Estimated reading time: 3 minutes, 21 seconds

Apex is an example of why RubyMotion is awesome

I was working on a very peculiar OS X application, which needed to communicate with an iPad app over the local network. There are a variety ways of doing an RPC (remote procedure call) from low level TCP/IP on up to something silly like SOAP.

I decided to try Apex from our favorite ProMotion author Jamon Holmgren. It would allow me to have a little web server in my OS X app that could serve JSON to my iPad app via rest calls.

That may sound a bit silly, but this app was local only with no Internet connection and as it’s going to run on a Mac Pro, so performance doesn’t matter.

It actually worked really well and was super trivial to use. However, I did have to add a few features to Apex first: JSON support and the ability to create a website in something other than the app delegate. Here is an example, you adding a web server to your app:

Add to gemfile:

gem 'apex', :git => 'https://github.com/clearsightstudio/apex.git'

Create this class:

class WebServer < Apex::Server
  port 8080

  get "/foo", response_type: :json do |request|
    result = SomeClass.some_method
    {success: result}
  end
end

Simple as that. In the iPad app I just used AFMotion to call the API I created in minutes. Pretty neat.


If you missed the last issue, you can find it here: issue #34.

Happy coding, Todd Werth (@twerth)

Articles, News, New Gems, and Blog Posts


July 29th, 2014 | meetup | by utwang
Yokohama City, Japan – Study session in Yokohama Mokumoku 1st RubyMotion

July 16th, 2014 | meetup | by NSFargo
Fargo, ND, USA – NSFargo Meetup

July 9th, 2014 | blog post | by Jack Watson-Hamblin
Is Swift Production Ready?

July 7th, 2014 | screencast | by Jack Watson-Hamblin
MotionInMotion – Episode 32 – Classes to Procs to Blocks

July 7th, 2014 | new gem | by Gant Laborde
motion-keychain – An easy RubyMotion gem for utilizing secure storage

July 3rd, 2014 | blog post | by Steve Ross
RubyMotion Testing Vacuum

Hidden Gem by Gant Laborde of Iconoclast Labs


Caveat when creating a RubyMotion gem: Most gems have a nice clean example app that comes with them in the /app folder. Some of us depend on this local app to help us iron out the kinks of the gem’s usage and examples. It’s also a great place to write the specs.

My hidden gem for you is a small nugget of information that will help you keep your sanity if you follow the aforementioned paradigm. Special thanks to Mark Rickert who helped me notice this issue before I lost my sanity trying to test the motion-keychain gem.

If you’re working on a gem that depends on a pod, the gem template cannot load the needed pod from the gemspec UGH! So you’ll just have to load a separate project, and point the gem’s :path => '../gem_name_here', OR load pods independent of your gem’s pod dependencies.

As far as I can tell, a pod dependency is the only situation limiting you from handling the whole bundle from utilizing a gemspec.

From the Archives

Because it’s easier to copy and paste than to write


Enable User Interaction

You may have noticed that gestures don’t work on images (such as tap). They actually do, but userInteractionEnabled is false on UIImageViews by default. You simply need to turn on user interactions. The same is true for UILabel.

my_view = UIImageView.alloc.initWithFrame([[100,100],[100,100]])
self.view.addSubview(my_view)
my_view.userInteractionEnabled = true
recognizer = UITapGestureRecognizer.alloc.initWithTarget(self, action: 'some_method')
my_view.addGestureRecognizer(recognizer)

Other types of views, such as UIButtons, default to true, thus why gestures work for them.

If you use RMQ, you can do this:

rmq.append(UIImageView, :style_name).enable_interaction.on(:tap) do |sender|
  # do something
end

One more thing


Whats you’re favorite ruby trick or quirk that most people don’t know about


If you have any tips, blog posts, or want to sponsor this newsletter, please send emails to todd@infinitered.com

Issue #34

  • Estimated reading time: 4 minutes, 21 seconds

Letters to the editor

I’m always looking for new columns to put in the Dispatch. One I’m working on is the latest updates from popular gems. I need to write a script for that because it would be way too time consuming to do manually.

Another idea I have is “Letters to the editor”, where you the reader send me your comments regarding the last issue. I then put them in the next issue (curated of course). So let’s try that and see if anyone is interested. Comment or ask a question about anything in this issue, and send those comments to me (todd@infinitered.com).


If you missed the last issue, you can find it here: issue #33.

Happy coding, Todd Werth (@twerth)

Articles, News, New Gems, and Blog Posts


July 2nd, 2014 | blog post | by RubyMotion
RubyMotion #inspect 2014 Wrap-Up

July 2nd, 2014 | blog post | by Kamil Lelonek
From Rails to RubyMotion: basic toolkit

July 1st, 2014 | blog post | by Todd Werth
RMQ version 0.6.1 released

June 30th, 2014 | video | by Nelson Pascoal
Rubymotion – iOS and OSX development from a Ruby developer’s perspective –

June 29th, 2014 | screencast | by Jack Watson-Hamblin
MotionInMotion – Episode 31 – Custom Video Players and Animating Videos

RubyMotion App of the Week


image

June 22th, 2014 – Green Light!

“Open source iOS app to interact with Semaphore

Github Repo

Gems this app uses

  • bubble-wrap
  • motion-cocoapods
  • afmotion
  • cdq
  • ib

Pods this app uses

  • SVProgressHUD
  • YIInnerShadowView
  • GBDeviceInfo
  • PrettyTimestamp

RubyMotion News


RubyMotion 2.30 released

  • The iOS 8.0 and OS X 10.10 versions of the runtime have been recompiled with Xcode 6 Beta 2.
  • Added the `device_name’ parameter in order to select iOS 8 simulater device. You can use “iPhone 4s”, “iPhone 5”, “iPhone 5s”, “iPad 2″ ,”iPad Retina”, “iPad Air”, “Resizable iPhone” and “Resizable iPad” for device name. (Ex rake device_name=”Resizable iPhone”)
  • Improved the compiler to optimize the app executable size, by removing unnecessary internal Objective-C stubs. Apps should be 10-30% lighter, depending on how much native calls they use.
  • Added the BigDecimal#{to_i, to_int, to_f, to_s, coerce, +@, -@, modulo, quo, power, floor, ceil, round} methods.
  • Added the Kernel#BigDecimal method.
  • Improved String interpolation performance. ~10% faster.
  • Improved the NoMethodError exception message to include the full Objective-C selector. Also, #method_missing will now receive the full Objective-C selector as the method name.
  • Fixed a bug where spec helpers nested in sub-directories were being considered spec files instead of helpers. Thanks to Ignacio Piantanida for the patch.
  • Fixed a bug where a crash due to an assertion would be happening when using #layout on a MIDIPacketList object on iOS 8.
  • Fixed a bug where a crash would happen when calling a Objective-C method supposed to return a block, but instead returning nil.
  • Fixed a bug where a crash would happen when a Symbol object was used with the NSCoding interface methods.
  • Fixed a bug where shortcut selectors would not work when the method name was begining or ending with a number.
  • Fixed a bug where the `scrollViewWillEndDragging:withVelocity: targetContentOffset:’ delegate method would not be defined properly.
  • Fixed a bug where a crash would happen when a Struct object was used with the NSCoding interface methods.
  • Fixed a bug where the NSJSONSerialization' interface would return a BigDecimal object if the0.0′ value was stored in the original JSON data.
  • Fixed a bug where dynamically-defined methods would not be removed properly.
  • Fixed a bug where typedef parameters would cause a “not precompiled” error.
  • [OSX] Fixed the runtime to recognize `NSTaggedPointerString’ objects that were introduced in Yosemite.
  • [OSX] Fixed a bug with the `NSManagedObjectModel#entitiesByName’ method of the CoreData framework where it would return an NSDictionary that was not expected on 10.9.
  • [OSX] Fixed a bug where the default value for `app.deployment_target’ was wrong and would cause a build error on an old version of OS X.
  • [OSX] Fixed a bug where a “not precompiled” error would happen when specifying an older version OS X version for `app.deployment_target’ when building on Yosemite.
sudo motion update

RubyMotion Tip of the Week by Marcos Villacampa


If you have multiple iOS devices connected to your computer, you can select in which one to run your RubyMotion application.

First, get the device UUID through iTunes or the Xcode organizer.

Then run your app like this:

rake device id=YOUR-UUID

Hidden Gem by Gant Laborde of Iconoclast Labs


Working on your project and just can’t remember the right syntax on that gem? Open that browser, and “O look at all these emails, and I haven’t even checked Reddit yet, today. O and my chat icon is blinking. What was I about to do? Was it watch cat videos?” The longer you’re out of code, the worse it gets. There’s something to be said about losing focus.

You may or may not be utilizing the RMQ gem, but today’s hidden gem is a delightful feature of the latest RMQ, that helps you gather information on the gem without breaking stride. Let’s say you wanted to review the RMQ grid diagram. You can now type rmq docs grid from your local shell, and have the gem pull up the appropriate documentation right on your local browser. Love it


If you have any tips, blog posts, or want to sponsor this newsletter, please send emails to todd@infinitered.com