Blog Moved!
Our blog is no longer hosted on Tumblr and is now available at http://rubymotion.com/news. Please update your bookmarks!
Monterey Bay Aquarium
will byers stan first human second
Alisa U Zemlji Chuda
NASA

Kiana Khansmith
Keni
YOU ARE THE REASON
cherry valley forever
Stranger Things

pixel skylines
Claire Keane

oozey mess

⁂
let's talk about Bridgerton tea, my ask is open
hello vonnie
Cosimo Galluzzi
Xuebing Du
occasionally subtle
Cosmic Funnies

Kaledo Art
seen from Germany

seen from Iraq

seen from New Zealand
seen from Russia

seen from Germany

seen from United States
seen from Singapore

seen from United States

seen from Türkiye
seen from United States
seen from United States

seen from Canada

seen from United States

seen from United States
seen from United States

seen from United States

seen from United States

seen from United States
seen from United States

seen from United States
@rubymotion-blog
Blog Moved!
Our blog is no longer hosted on Tumblr and is now available at http://rubymotion.com/news. Please update your bookmarks!
RubyMotion for Android and Renewals Pricing
Since the introduction of the public beta of RubyMotion for Android last week there have been questions about the future pricing of RubyMotion, and rightfully so. This post will address this in as simple and open a way as possible.
RubyMotion for Android
After long deliberation, the team decided that RubyMotion should be a single product that supports iOS, OS X, and now Android as well. It is our belief that the vast majority of mobile developers have to (or would like to) target both iOS and Android. Therefore it makes more sense to us to provide support for all platforms in a single package over selling multiple separate packages.
Thus, there will be no extra charge for the Android version of RubyMotion. Yes, you read that right, 0 extra euros, dollars, or even yen!
With just a one-click purchase, one will be able to write iOS, Android and Mac apps, all using the same toolchain, language and text editor.
Updates and support renewal
In the past, RubyMotion has been a one-time purchase that came with one year of updates & support and it was possible to renew the updates & support at half the price of the full license. However, with several thousand customers, the math makes it so that this is no longer sustainable over the long term.
For one thing, we have been answering many support questions concerning more than just the RubyMotion toolchain. We take pride in being able to do this because we care about our customers, and we want everyone's experience building RubyMotion apps to be a good one. As a nice side-effect, this has allowed us to respond to your needs by putting out regular monthly software updates that improve the total experience for all our customers. We believe it is in everyone's best interest to keep doing this, but the fact is that we are now increasing our workload by a factor of 2 with the addition of the Android platform.
Therefore, RubyMotion license renewals will now be priced at the same price as a new licenses. This will help us better scale our organization for the development, maintenance, and our support of RubyMotion for everyone going forward into this new bright future.
To summarize, annual charges will be set at $199,-. That's only $16.50 a month. We personally spend more than that on coffee ;)
Thank you all for your continued support! Without it we could not be a fully bootstrapped company, free of investors saying what we should do over what we think is important for you, our customers.
Announcing the public Beta of RubyMotion for Android
We are super excited to announce that RubyMotion for Android is now available in public beta.
Since its introduction in May, during our annual developer conference in San Francisco, we have been working extremely hard on RubyMotion for Android, with the goal that it should be usable by early adopters.
While functional and relatively stable, RubyMotion for Android is still not ready for prime time yet. However, we do believe that it can be used by seasoned developers and we hope that we will receive enough feedback to polish the product enough that it can be used by everyone.
Availability
The RubyMotion for Android public beta is free for all customers.
Getting started
After applying the latest software update, you can install the beta by using the following command:
$ sudo motion update # make sure you have the latest update $ sudo motion update --pre # install the pre-release beta
Please follow the Getting Started guide for more information on how to set up a proper Android development environment.
Features
RubyMotion supports the following versions of Android: 1.5, 1.6, 2.1, 2.2, 2.3, 3.0, 3.1, 3.2, 4.0, 4.1, 4.2, 4.3, 4.4 and L (latest).
RubyMotion for Android apps are statically compiled into ARM machine code using our ahead-of-time (AOT) compiler. Both armv5te and armv7 architectures are supported by the compiler.
The RubyMotion for Android runtime features a brand-new implementation of Ruby, based on Java. You get to call into the entire set of Java APIs. Check out the Runtime guide for more information. Both Dalvik and ART runtimes are supported.
The command-line interface features a REPL (interactive console) that works on both the Android emulator and a USB-connected device. This works by doing remote JIT compilations from the Mac to ARM.
RubyMotion for Android apps can also vendor third-party Java libraries (jar files) and can be submitted to the Google Play store.
Make sure to check out the Android samples from our repository.
Our friends at MotionInMotion are working on RubyMotion for Android screencasts. Stay tuned!
Future work
Here are the things we will be doing in the soon future:
Performance work; at this stage all optimizations are disabled and a lot of logging is going on (for debugging purposes). Don't try to benchmark it.
The runtime is still missing a lot of builtin Ruby classes and methods.
A Mac computer is required. Some of you guys have been asking for Linux support, if there is enough demand we might consider it.
We will provide builtin support for the other Android APIs (such as Android Wear, Android Car, etc.).
We need your help
RubyMotion for Android is still a beta at this stage. Please give it a try and report bugs to us. Your help will be essential to help us make RubyMotion for Android ready for everyone. Also, please keep in mind that this is a beta, bugs are expected!
Enjoy!
RubyMotion #inspect 2014 Wrap-Up
This year's RubyMotion conference was immediately followed up with WWDC and then Google I/O, so we've hardly had a chance to sit back and reflect on all the exciting news that emerged from #inspect!
The Fort Mason Center
As much as we enjoyed cramming 150+ people into a tiny room last year, we decided that maybe a little more leg room wouldn't go unappreciated:
This year's conference was at the historic Fort Mason Center, near Fisherman's Wharf. If you need to plan an event in San Francisco, put this one on your radar. The view of the marina and Golden Gate Bridge was a very pleasant back drop.
Food and Libations
This year's catering was amazing, in keeping with the traditions set at #inspect 2013. We should all take a moment to thank Todd Werth and Ken Miller from InfiniteRed for organizing the catering, which was provided by Local Mission Market.
For the after party we invited Rogue Brewery to share five of their popular and most delicious beers, and no one (yes, even Laurent) left disappointed. Turns out that tasty food and tasty beer go a long way towards a successful conference!
Knowledge was Dropped
It's fun to play with new gems, but you won't get far if you don't know what the operating system is capable of. This years' speakers had a ton of information to share with us.
Mark Rickert has been sharing great marketing tips in the RubyMotion Dispatch. He had even more advice for us, including some of his own successes for context. Wearing the marketing hat doesn't need to be painful, and it's essential for the success of your apps. (slides, video)
We heard about the trials and tribulations of CoreData from Lori Olson. She needed to import tens of thousands of records into her app, which it turns out is no small task! Core Data can handle it, but handling Core Data is another matter. (slides, video)
To help wrangle that behemoth of a library, Ken Miller created CoreDataQuery and ruby-xcdm. It's not just a DSL around CoreData, it produces the same XML files that are created from Xcode's GUI. This means that it has feature parity with the traditional Xcode tools, in particular migrations are supported. (slides, video)
Jack Watson-Hamblin creates the MotionInMotion screencasts, and he has some great advice for anyone who wants to learn and help: teach! It's never too early or late to share what you have learned. (slides, video)
For anyone interested in game development, Will Raxworthy showed us how incredibly easy it is to build a game with SpriteKit and RubyMotion. He built the entire app before our eyes, with gravity and collision detection, all in a simple to understand object-oriented framework. (slides, video)
Dave Lee is a core contributor to the ReactiveCocoa project, which is at the same time powerful and daunting. Dave showed us what a RAC refactor looks like, and how you can benefit from the reactive code style. (video)
On the more practical side of things, we watched Dennis Ushakov demo the RubyMotion features that are baked into RubyMine. It's not just for Rails! Debugging, refactoring, and code-aware autocomplete are all available. (video)
There's a ton of money to be made in the under-served enterprise arena, and Kevin Poorman showed us just how easy it is to make apps that cater to that community, using SalesForce as an example. (video)
When Alex Rothenberg started developing in iOS he quickly realized that "Cocoa is no Rails". It's verbose, obtuse, and also verbose and verbose. Something had to be done, and Alex shared ideas about how Ruby paradigms can fit nicely in Cocoa. (video)
We heard from Ivan Acosta-Rubio about his successes (and frustrations!) working with (and wrestling with) the AVFoundation framework to produce images and video. Turns out it's easy, once you understand the players. (video)
We had a TON of fun watching Mark Villacampa control a tiny robot from his phone! Mark discussed the various iOS-to-hardware communication options that are available. (video)
Testing junkies were happily sated with Isaac Murchie's demo of Appium. It takes iOS testing into the cloud, making it much faster and thorough than what you can accomplish with good ol' rake spec. (slides, video)
We also heard from three developers who are working on projects that are experiencing the kind of problem we all hope for: Success! We heard from Ryan Romanchuk from Frontback, Daniel Dickison from BandCamp, and our own Colin Gray from Jukely. With Gant Laborde asking questions (and fielding questions from the audience), we discussed how we chose RubyMotion, how we test our apps, and what we do to make sure we're shipping solid applications. (video)
Gems were shared
What a productive year it's been for the RubyMotion community! I don't have the space here to gush over all the gems and features that were featured or released at #inspect, but here are some that stand out:
Clay Allsopp demoed some of the build tools have been created at Propeller. Everything from automated screenshot testing (with diffs!) to command-line based deployment tools. From start to deploy, you never have to leave the terminal! Learn about them all at Propeller's github organization: https://github.com/usepropeller (slides, video)
From Todd Werth at InfiniteRed, the RMQ library has been expanded to include a wealth of REPL tools, a grid-based layout engine, and a documentation website that puts the rest of the WORLD'S to shame: http://rubymotionquery.com (slides, video)
Jamon Holmgren has big plans for the 2.0 release of ProMotion: more screens, a modular design, and he hinted at possible Android support! (slides, video)
Colin Gray and Jamon Holmgren have been working on a new layout tool to replace Teacup called MotionKit. Its goal is to encourage lighter controllers by moving layout, styling, and animation code into a new class: the Layout. The end result? (slides, video)
At last year's #inspect someone asked Austin Seraphin if "automated accessibility testing" would be possible... this year it was announced! The motion-accessibility gem has seen huge updates over the course of a year. A REPL-based browser, automated testing for your specs, and of course a light, terse DSL that makes it easy to update your app with accessibility in mind. (video, article)
And joining us from Australia via Skype, Nikolay Nimshelov gave a demo of his awe-inspiring gem UnderOS, which brings HTML, CSS, and web paradigms to iOS. It's really remarkable! (video)
RubyMotion is FAST
When we need to defend our claim that "RubyMotion is Fast", we should thank the long-time MacRuby and RubyMotion developer Shizuo Fujita (aka Watson). Watson optimizes every aspect of the RubyMotion compiler and runtime so that our apps run just as fast as their Objective-C brethren. RubyMotion 3.0 has a ton of performance increases thanks to his work. He shared the improvements he's been working on, including some benchmarking tools that we can all use to improve our own code: motion-benchmark and motion-benchmark-ips.
The runner up to the big announcement
We're all really excited for the "big announcement" this year, but standing tall and proud in the shadow of that announcement is Eloy Duran's new code-reloading tool that had everyone's jaw resting firmly on the floor. A save, a quick code compile, and your updated code is injected into your app while it is still running in the simulator. Eloy showed us how this feature decreases the time it takes to style views and try new features. This is going to drastically change the face of RubyMotion development in iOS.
The big one
The internet was all a-buzz about this year's big announcement: Android support is coming to RubyMotion. It has everything we already enjoy in iOS and OS X:
Compiles to native code, no bridging involved
Native Ruby classes extend existing Java classes
Terminal-based workflow
Rakefile-based project configuration
And best of all: the RubyMotion community ;-)
Laurent demoed some apps that he's written that are already running. They launched immediately and ran smoothly. As promised, they have the same performance characteristics as an app written in Java. Those sample apps are available in the HipByte's github organization.
The entire State of the Union talk, with Watson, Eloy, and Laurent is available to watch online.
Summary
Last year was all about affirming that RubyMotion isn't just some toy that Rubyists like to play with, it's a development tool that is powering complex consumer apps. This year showed that not only has that trend continued, but it's grown at an accelerated rate! We're more productive and having more fun than ever.
We're entering the Android arena at a ripe time for the platform: Android L is a huge step forward in design, and all the new Android platforms (TV, auto, wearables) are all supported in RubyMotion.
This year is going to be a great year for Android and cross-platform gems! We're very excited to see what you come up with! See you all at #inspect 2015!
RubyMotion 3.0 Sneak Peek: Android Support
It's very sunny here in San Francisco, California, and we are super excited to give you a first sneak peek at the next major version of RubyMotion, numbered 3.0, which will be released later this year!
Android Support
RubyMotion 3.0 features support for a new mobile platform: Android. You can now write full-fledged Android apps in Ruby instead of Java. If you have a RubyMotion app for iOS or OS X and want to port it to Android, you can even share some of the code! One language, three platforms.
RubyMotion Android projects are created and managed exactly the same way as RubyMotion iOS and OS X projects. The --template=android argument can be passed to motion create to create a new Android project.
$ motion create --template=android Hello Create Hello Create Hello/.gitignore Create Hello/app/main_activity.rb Create Hello/Rakefile Create Hello/resources Create Hello/assets $ cd Hello $ rake
The entire project configuration lives in the Rakefile. RubyMotion for Android features a build system driven by Rake tasks, similar to what we already do for the other platforms. You can build and run apps in the Android emulator (rake emulator), on your USB-connected Android device (rake device), and prepare and sign builds suitable for a Google Play submission (rake release).
The AndroidManifest.xml file (similar to iOS' Info.plist file) is also generated based on the values in the Rakefile.
You can keep using your favorite editor when working on an Android project in RubyMotion: Eclipse is not required nor used in any part of the process. In addition, ctags-based editors will have auto-completion for Java APIs.
Android projects can also vendor 3rd-party Java libraries, similar to how iOS and OS X projects can vendor 3rd-party Objective-C libraries. If you need a MapView in your app, integrating the Google Play Services library is just one app.vendor_project call away.
In a RubyMotion Android projects, raw resource files can be added to the assets directory, while special application-level resources can exist in the resources directory. The build system will make sure these are properly packaged and identifiable via the R class.
Runtime
RubyMotion for Android features a completely new Ruby runtime specifically designed and implemented for Android development. This is a new implementation of the Ruby language, it does not share code with RubyMotion for the Objective-C runtime. We are using the RubySpec project to make sure the runtime behaves as expected.
class MainActivity < Android::App::Activity def onCreate(savedInstanceState) super text = Android::Widget::TextView.new(self) text.text = 'Hello World!' self.contentView = text end end
The object model of RubyMotion for Android is based on Java. Ruby classes, objects, methods and exceptions are Java classes, objects, methods and exceptions, and vice-versa. No bridge is involved.
The Ruby builtin classes are also based on core Java classes:
Fixnum is based on java.lang.Integer
Float is based on java.lang.Float
String is based on java.lang.CharSequence
Array is based on java.util.ArrayList
Hash is based on java.util.HashMap
Regexp is based on java.util.regex.Pattern
Thread is based on based on java.lang.Thread
etc.
This unified runtime approach provides an excellent integration with Java APIs as well as good performance, since objects do not have to be bridged. The runtime uses the Java Native Interface (JNI) in order to integrate with Java, and the entire set of Android APIs is available in Ruby, out of the box.
The memory management is delegated to Dalvik's generational and concurrent garbage collector. The runtime creates and destroys global references when needed (such as when an instance variable is set), and the destruction of local references is determined at compile time.
The garbage collector is very efficient; it features a per-thread allocation pool for fast allocations, finalizations can happen on dedicated threads, and cycles are properly handled.
Compiler
RubyMotion Android apps are fully compiled into optimized machine code, exactly like their iOS and OS X counterparts.
We feature an LLVM-based static compiler that will transform Ruby source files into ARM machine code. The generated machine code contains functions that conform to JNI so that they can be inserted into the Java runtime as is.
Since Android does not allow classes to be created at runtime, the compiler will emit DEX byte-code for class interfaces, but mark all methods as defined in native code.
The compiler also emits DWARF metadata, which lets us properly symbolicate exceptions, and also allows us to set source-level breakpoints when attaching a debugger.
The build system links all object files with the RubyMotion runtime in order to create an NDK shared library.
RubyMotion Android apps are packaged as .apk archives, exactly like Java-written apps. They weight about 500KB by default and start as fast as Java-written apps. All Android API levels are supported.
Samples
We are extremely excited about RubyMotion for Android. We can finally use the same language to develop an application for multiple platforms, and even if platform-specific code (ex. user interface) will have to be written, we do believe that a significant part of the app, such as the backend, can be shared.
We spent the last days working on sample code apps.
We also created an application for our conference, which has been submitted and is available in the Google Play store. If you have an Android device, check it out! The source code will be published on GitHub right after the conference.
We Need Your Help
RubyMotion 3.0 is not ready for prime-time yet. We are working hard on improving and polishing it so that it can be delivered to everyone.
The reason we are giving you a sneak peek today is because we can't achieve that without you. RubyMotion for Android features a brand-new implementation of Ruby that will require significant testing before it can be as mature as the existing RubyMotion platforms support.
We are looking for volunteers interested in accessing early builds of RubyMotion 3.0, testing the new features and giving us continuous feedback so that we can quickly iterate.
Are you the author of a RubyMotion gem that you think would make sense to exist for Android? Do you have an app in the App Store that you would like to port and submit to the Google Play Store? Are you willing to test early builds of RubyMotion for Android, report bugs and work with us? We need your help.
If you are interested, please fill out this form. We will only approve a small amount of developers for the beta, and we will start seeding the first builds in early July. Thanks a lot!
New in RubyMotion: BigDecimal, Better Localization
The last RubyMotion releases introduced a couple high-level changes that we would like to cover, before we get to start our second developer conference, next week!
BigDecimal
As of RubyMotion 2.28, the BigDecimal class is introduced, based on top of Cocoa's NSDecimalNumber class.
It implements all of CRuby's BigDecimal operator methods, and can be passed to Objective-C APIs that expect arguments as NSDecimalNumber objects, NSDecimal structures, or pointers to NSDecimal structures.
NSDecimalNumber objects are therefore not converted to Float objects anymore, and remain intact when passed to and retrieved from Objective-C APIs.
In case your application requires high-precision representations for floating point objects, we recommend using BigDecimal instead of Float.
(main)> x = BigDecimal.new('0.123456789') => 0.123456789 (main)> x + 1 => 1.123456789
Better Localization
The build system has been improved to detect and properly compile strings resource files into the application bundle. This patch was contributed by Hwee-Boon Yar.
Additionally, the NSLocalizedString() API and its variants, NSLocalizedStringFromTable(), NSLocalizedStringFromTableInBundle() and NSLocalizedStringWithDefaultValue(), have been added as methods of the Kernel module. Previously they were not available as they are C-level preprocessor macros, and one had to call the NSBundle Objective-C API directly.
String resource files are usually used to localize an application, by providing the translations of user interface strings. A resource file per localization is the norm.
RubyMotion #inspect 2014: Last Speakers, Panel, Schedule
In about a month we will be launching our second annual developer conference, #inspect, the 28th and 29th May in sunny San Francisco, California.
RubyMotion #inspect 2014 will be a 2-day single track conference, 100% about RubyMotion. We picked an awesome venue, Fort Mason, a former US military post office which offers a scenic view of the famous Golden Gate Bridge.
We are obviously super excited about the conference. Make sure to grab a ticket when you can, we are selling those fast.
Last Speakers
We are now revealing the last 6 speakers, in addition to 16 already-announced speakers:
Kevin Poorman is a software architect at West Monroe Partners and a certified Force.com developer. He authored several RubyMotion apps, all tied to the Salesforce enterprise resource, and will talk about connecting RubyMotion to enterprise systems.
Andy Pliszka works at Pivotal Labs on large iOS projects. He will talk about setting up RubyMotion for Test-Driven Development (TDD) and how to leverage test-first methodology when building RubyMotion projects.
Ivan Acosta-Rubio writes iOS apps using RubyMotion at Software Criollo. In his talk, Ivan will introduce the AV-Foundation framework and how to capture media on iOS and OS X. Let's write some spying tools!
Isaac Murchie works at Sauce Labs and will talk about using tried-and-true Ruby tools, such as RSpec, Cucumber and Capybara, to automate the testing of RubyMotion projects with Appium, in order to deliver robust mobile apps.
Paul Colton is the co-Founder and CEO of Pixate. Paul will review the Freestyle framework and how it can be used to style RubyMotion apps using just plain CSS.
Mark Villacampa works for Cabify on their RubyMotion app and is also a hardware enthusiast, hacking 3D printers. Mark will talk about connecting RubyMotion to hardware, walk through all the available options, and giving recommendations for the folks interested to try at home.
This ends our speakers selection for this year! If you submitted a proposal and didn't get in we are truly sorry. We got a lot of proposals this year and it was tough to make the pick!
Panel
We will be organizing a panel dedicated to RubyMotion apps in production.
The panel will be composed of folks working on high-profile RubyMotion apps, such as Bandcamp, Jukely, A Dark Room (which is at the time of this writing, number one in the top-paid category of the US App Store!), and possibly Frontback and Jimdo.
We will discuss their experience, common pitfalls when working on a high-profile RubyMotion app, then take questions from the audience.
Schedule
We published the schedule of the conference. One keynote, 20 presentations, one panel. As you can see, it's fully packed with awesomeness!
We still have tickets available, so if you want to join us, now is the time, register today!
RubyMotion #inspect 2014: Announcing More Speakers, Student Tickets
In a bit more than a month, the 28th and 29th May, we will be launching our second annual developer conference, #inspect, this time in sunny San Francisco, California.
RubyMotion #inspect 2014 will be a 2-day single track conference, 100% about RubyMotion. We picked an awesome venue, Fort Mason, a former US military post office which offers a scenic view of the famous Golden Gate Bridge.
We are obviously super excited about the conference. Make sure to grab a ticket when you can, we are selling those fast.
More Speakers
We are happy to reveal four more awesome speakers, in addition to 12 already-announced speakers:
Alex Rothenberg is a software engineer at McKinsey and the author of the motion-addressbook library. He will talk about simplifying the Cocoa APIs and making sure they do not crush your Ruby code.
Dennis Ushakov, a software engineer at JetBrains, will show off RubyMine and its excellent integration with the RubyMotion toolchain.
Nikolay Nemshilov is a senior software developer at Ninefold and also the author of UnderOS (or shortly, uOS), a project that aims to help web-developers to get into native iOS development by reusing knowledge and technologies they already know, which he will present.
Austin Seraphin is a blind developer and an accessibility expert. Austin was a speaker at #inspect 2013 last year and delivered one of the most acclaimed presentations. Since then, he authored the motion-accessibility gem and will talk about how making RubyMotion apps accessible to the blind.
We will be announcing the last batch of speakers soon. If you submitted a talk proposal, we will get back to you as soon as we can. Thanks for your patience!
Student Tickets
Due to the demand we will be offering a limited batch of tickets for students to the conference at a highly discounted price.
Students tickets are priced at $149 and require proof of enrollment. Please email us in order to get one. We will update this post once the batch will be gone.
Call for Sponsors
We are still looking for a small number of sponsors to share in the support of #inspect 2014. This is a great opportunity to show your commitment to the RubyMotion community and also promote your products or services. If you or your company are interested get in touch.
RubyMotion Success Story: A Dark Room
A Dark Room is a very popular text-based role playing game (RPG). Originally web-based, Amir Rajan ported it to iOS using RubyMotion, and very quickly the app went from being the top game in the RPG category to be in the top 5 paid apps in the UK App Store. At the time of this writing it's on its way to the top paid category of the US App Store.
The game now enjoys a 5-star rating and has been positively covered numerous times in the press.
We sat down with Amir to discuss his experience building this awesome game in RubyMotion.
What is your background, and what brought you to become involved in RubyMotion?
Before I took my sabbatical (I guess you can say I've gone independent now), my entire 8 year development career was all .Net development. I used ruby primarily for build automation during my day time job. Outside of my 9-5, side work I did was primarily Rails and NodeJS. I've contributed quite a bit to the open source .Net community. I'm a contributor to NSpec (an RSpec clone), SpecWatchr (an auto test tool for NSpec), Oak (a dynamic "poly fill" for C# andASP.NET MVC), and Canopy F# (a Web UI automation DSL for Selenium and PhantomJS).
One of my friends told me about RubyMotion. I was immediately interested given that I had an appetite for "different ways" (better ways) to approach problems.
Why did you choose to use RubyMotion instead of Xcode and Objective-C?
My first few apps that I built (none of which made it into the App Store) were actually built using Xcode and Objective C. Notably, I built a little budgeting app for myself with a Rails back end. At that time I actually had RubyMotion but wanted to have a solid basis of "vanilla" iOS development before making an assessment on RubyMotion.
One thing I saw immediately was the contrast between the work I did on the server side Rails app vs when I went back to Xcode. The hardest things to explain is the "Ruby mindset": light weight environments, concise workflows, editor agnostic, fast feedback loops, simple API's... essentially developer happiness.
As painful as it was to work outside of my souped up VIM environment, I completed my budgeting app using Xcode and Objective C for the client side. I did not enjoy the experience. Objective C is verbose, the Cocoa API's are unintuitive, a lot of ceremony with regards to class definitions. Xcode makes it difficult to work with vendor libraries (try referencing AFNetworking for HTTP communication and Cedar for testing if you don't believe me). Interface Builder was frustrating to work with too.
Now that I had my perspective, I worked with RubyMotion instead. The wrappers are wonderful (I primarily used BubbleWrap and Promotion). The rake tasks that come out of the box are great. Testing is first class, MacBacon has an RSpec style DSL that I know well and enjoy working with. Package management is solid, and I was able to use Objective-C libraries via CocoaPods. It just felt like everything was thought through, distilled down, and presented in a form that was immediately familiar to me given my Ruby background (and the "Ruby mindset").
What inspired you to create “A Dark Room”?
A Dark Room is actually a joint venture between myself an Michael Townsend. He created the web version of the game. It went viral on Hacker News and I stumbled across it. At this time I was on a sabbatical, and decided that this would be a wonderful project to take on. I absolutely loved the web version of the game, but it wasn't touch device compatible. I sent an email to Michael, asking if I could port it to iOS. He said yes! 4 months and 12,000 lines of RubyMotion later, I had a game in the App Store.
How did you begin writing the app, what were your early development stages?
I had some real world experience with Xcode and Objective C. In fact, the first few hours of A Dark Room development was done in in Xcode. I wanted to start fleshing out the engine of the game, and found it rather awkward using OCUnit. I rely heavily on fast feedback loops and incremental evolution. OCUnit did a good job in giving feedback, but fell short when it came to test composition. I refactored often, and what I found was that Objective C and OCUnit just made that an utter chore. I had a copy of RubyMotion, I knew that it had an RSpec style testing framework, and I knew how easy it was to refactor Ruby code. So I put the Obj C version of A Dark Room aside, and fired up RubyMotion.
I was extremely happy with the default template. Testing was baked in, the rake tasks were already in place to run tests. I created a light weight watchr script to run tests whenever I saved a file... everything just gelled really well :-)
As the game progressed, how difficult was it to add and remove features from your code base?
Not knowing RubyMotion, I initially stuck to using "vanilla" Cocoa apis for all my UI work. It was extremely easy to translate Objective C to Ruby. I was able to use all the resources on Stack Overflow whenever I hit a snag. Eventually, I was juggling a number of views and decided to look at ProMotion and BubbleWrap (which I found via the RubyMotion Wrappers site). The refactoring was easy. It amounted to deleting code ;-).
As far as the core game engine, I was able to use all the refactoring techniques of Ruby. All the language capabilities "just worked": inheritence, class macros, modules/mixins, "send", blocks, etc. My tests were always running in the background with every change I made.
Your app has been praised as being one of the few games that have are accessible to the blind. What did you do to make sure your app was accessible?
Accessibility changes were surprisingly simple to make. It's amazing how much iOS does for you out of the box. Most of the first part of the game was already playable via VoiceOver. I ended up using an existing Objective-C open source library called SSAccessibility (it did all the hard work with regards to queueing multiple messages). I used CocoaPods to install the library, updated my Rakefile, and was up and running. The key take away here is that I was able to leverage the existing Objective-C ecosystem. Here is a write up of all the quirks with regards to making accessible apps.
What were some of your greatest, happiest moments during development?
Shipping. It's hard to believe that the code base was over 12,000 lines. I was happy to get this mammoth out the door.
Were there times that the RubyMotion toolchain was a source of frustration? And how did you get those issues resolved?
I had a couple of instances where RubyMotion would throw a runtime exception without a backtrace (stacktrace). It was always related to the initial load of the app's UIViews. I'd use git bisect to zero in on what line caused the error. It was tedious work at times.
Will you continue to use the RubyMotion compiler on future projects?
Absolutely. Without hesitation. Idiomatic Ruby wrappers on top of iOS, frictionless workflows, and the "it just works" culture that Ruby fosters, trumps any hesitation I once had. On top of that, I now have a fairly large app to serve as a testament to the platform.
RubyMotion #inspect 2014: First Batch of Speakers, Lodging Information, Sponsors
In a bit less than two months we will be launching our second annual developer conference, the 28th and 29th May in sunny San Francisco, California!
(Yes, that's the week before WWDC!)
RubyMotion #inspect 2014 will be a 2-day single track conference, 100% about RubyMotion. We picked an awesome venue, Fort Mason, a former US military post office which offers a scenic view of the famous Golden Gate Bridge.
First Batch of Speakers
We closed our call for presentations and are now working on finalizing the schedule. In the meantime, we already pre-selected some of the speakers and it is our pleasure to list them here!
Laurent Sansonetti, Shizuo Fujita and Eloy Durán from HipByte will share a keynote talk in which they will talk about what's coming next for RubyMotion (we think you will like it!).
Clay Allsopp, author of the Pragmatic Programmers' RubyMotion book and numerous libraries will talk about building build tools that build tools to build apps. Sounds crazy and interesting!
Jack Watson-Hamblin, creator of MotionInMotion, the popular weekly screencast, will talk about the RubyMotion community and what we can do to make it better.
Lori Olson, author of a RubyMotion book about Core Data, will share her experience in solving real problems using Core Data in RubyMotion apps.
Todd Werth, co-founder of InfiniteRed and author of the popular RubyMotionQuery (RMQ) library will talk about what's new in RMQ. Todd is also co-organizing the event!
Jamon Holmgren, owner of ClearSight Studio and author of the popular ProMotion framework, will talk about going from a prototype to a production app.
Mark Rickert, owner of Mohawk Apps, is the author of numerous RubyMotion apps, all of which are open-source. Mark also has a lot of experience marketing apps and will teach us a few tricks on how to promote an app in the App Store and through other channels.
Ken Miller, co-founder of InfiniteRed, is the author of CoreDataQuery (CDQ), a library which aims at making Core Data easier to use. Ken will talk about CDQ and what's new.
Dave Lee is a contributor to ReactiveCocoa, a framework that provides Functional Reactive Programming to Cocoa apps. Dave will talk about integrating ReactiveCocoa in RubyMotion.
Will Raxworthy, author of numerous blog posts about RubyMotion, will talk about 2D game development, using the new SpriteKit framework and integrating with native game controllers, and eventually write a Flappy Bird clone!
We will be announcing more speakers soon. If you submitted a talk proposal, we will get back to you as soon as can. Thanks for your patience!
Lodging Information
The conference is located between the Fisherman's Wharf and the Marina district. Both are within easy walking distance and both have public transportation.
The Wharf has many places to stay because it's a tourist location. There are a lot of tourist-area places to eat too. You won't see a lot of San Franciscans in this area, but there is a lot going on and it is fun.
The Marina is a local neighborhood, but there are a lot of motels/hotels on Lombard street. The Marina is cheaper than the Wharf.
There are plenty of other neighborhoods to stay in too. The Mission district is where a lot of tech workers live and is an Uber car-ride away. Union Square is a popular location and is a MUNI 30 bus away (or Uber). SOMA and Market Street are where many of the startups are.
Check out the lodging section of the conference website for more information and also pointers to places we recommend.
Sponsors
We are delighted to announce that Pixate will be our lead (gold) sponsor this year!
Pixate was founded in the summer of 2012 as a Y-Combinator company with the goal of enabling designers and developers to quickly and easily create beautiful, native mobile applications. Their flagship product, Pixate Freestyle, enables the styling of native mobile applications using CSS.
A few words from our silver sponsors:
Terrible Labs is a design and development shop in Boston. They use RubyMotion to build all of their clients' iOS applications. They have also used RubyMotion to build their own product, TicketZen, the easiest way to pay parking tickets.
RubyMine, the most powerful Ruby IDE, provides smart coding assistance and advanced testing and debugging features for all types of Ruby projects and cutting-edge technologies, including RubyMotion.
We would like to thank Pixate, Terrible Labs and RubyMine for helping us organizing this awesome event.
We are still looking for a small number of sponsors to share in the support of #inspect 2014. This is a great opportunity to show your commitment to the RubyMotion community and also promote your products or services. If you or your company are interested get in touch.
RubyMotion Raises Millions, Becomes Free, Introduces Smart Suggestions™
Update: We hope that you folks enjoyed our April Fools prank! We are of course still 100% bootstrapped. We also still intend to grow organically thanks to your continuous support!
(Personal thanks to Josh Ballanco for having had the idea of RubyMotionCoin and MotionInflater.)
We are delighted to announce on this 1st April 2014 that we just closed a multi-million dollar funding transaction with Agile Ventures and Extreme Capital, two top-tier investing firms of Silicon Valley.
This is our first series A round of funding and we are extremely excited about the future of RubyMotion. Make sure to read the coverage on TechCrunch (to be published later today). You can also check a picture of our new board of directors and observe the synergy already at work.
We have been bootstrapping RubyMotion since its inception and were profitable by charging our awesome customers (from here on out referred to as users), but we think it's now time to shift into the next gear.
Our goal is to grow RubyMotion faster into a 100-people company serving millions of users and bringing you folks tons of innovation. The entire team will also relocate into the San Francisco Bay Area (including Eloy's new boat which presents a set of interesting logistic challenges).
We are of course still committed to a long-term vision. Unlike the majority of VC firms, our new partners Agile Venture and Extreme Capital are there for the long run and will definitely not require an exit in the next four years. (At least they said so during our meetings.)
Free, Smart Suggestions
Thanks to this funding round we no longer need to get money from you folks, so RubyMotion will become totally free. Awesome isn't it?
We will also ship with a new feature called Smart Suggestions™ (patent pending). The RubyMotion build system will now show you suggestions of services you might want to use by scanning your project's source code, sending us a copy, and getting back a list of relevant services. (Please note that the connection to our server is totally secure by using the same cryptography algorithms used in banks, so you should feel safe.)
Here is an example of what a future project build session might look like.
Compile app/person.rb !!! It looks like you are creating a regular expressions on line 42. RegexBuilder™ is a new revolutionary tool that makes building regular expressions easier. Would you like to know more? [Yy] [...]
We believe that Smart Suggestions™ will significantly increase your productivity, so we are enabling it by default for all users. Please contact our sales team if you would like to disable Smart Suggestions™.
Future Plans
Very soon we will be introducing RubyMotionCoin, a new virtual currency that is mined as a byproduct of the Xcode build system. If you include a CocoaPod in your app that contains Objective-C++ code using templates, your mining rate doubles.
Finally, we will be releasing MotionInflater later this year, a system that will automatically convert your RubyMotion code to Objective-C, ensuring that your app gains the approval of important people and allowing you to experience the inflated ego that can only come from shipping a real iOS app.
New in RubyMotion: New CLI, WeakRef Zeroing, Background Fetch Testing, Subscripting, Performance
We shipped quite a few releases since the beginning of the year. Let's dig into the new major features.
New Command-Line Interface
The motion command-line interface has been fully rewritten using the CLAide project.
$ motion RubyMotion lets you develop native iOS and OS X applications using the awesome Ruby language. Commands: * account Access account details. * activate Activate software license. * changelog View the changelog. * create Create a new project. * device-console Print iOS device logs * ri Display API reference. * support Create a support ticket. * update Update the software. Options: --version Show the version of RubyMotion --no-ansi Show output without ANSI codes --verbose Show more debugging information --help Show help banner of specified command
The new codebase allows better output and more elaborated argument handling. It will also allow us to extend the interface more easily in the future.
WeakRef Zeroing
In previous builds, trying to send a message to a WeakRef object whose internal reference was prematurely destroyed was causing a crash at runtime, since it was attempting to send a message to an invalid object address.
Now, the internal reference of WeakRef objects will properly be zeroed when it is destroyed. Sending a WeakRef object a message whose internal reference has been zeroed will cause a WeakRefError exception at runtime, matching exactly the behavior of CRuby's weakref.rb standard library.
The WeakRef#weakref_alive? method was also added and will return false in case the internal reference has been zeroed.
autorelease_pool do @ref = WeakRef.new(Object.new) end @ref.weakref_alive? #=> false @ref.description #=> WeakRefError: Invalid Reference - probably recycled
Background Fetch Testing
iOS 7 introduced the notion of background fetch which for example allows your application to check a remote web API if there is any updated content and, if so, fetch it, all while being in a suspended state.
To perform a background fetch iOS will launch your application using the application:performFetchWithCompletionHandler: method. You can now simulate this on the iOS Simulator by setting the background_fetch environment variable, as show below.
$ rake background_fetch=1
Note that while your application is in the background you will not be able to REPL until you activate the application again.
Object Subscripting
As of clang 3.1 Objective-C developers are able to add support for the new Objective-C literal syntax on their own classes by implementing a set of methods.
RubyMotion will now properly handle objects from these classes and allow you to send the #[] and #[]= messages on them as convenience shortcuts.
As an example, let's take a fictional SubscriptingExample Objective-C class:
@implementation SubscriptingExample - (id)objectAtIndexedSubscript:(NSUInteger)index; { ... } - (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index; { ... } - (id)objectForKeyedSubscript:(id)key; { ... } - (void)setObject:(id)object forKeyedSubscript:(id)key; { ... } @end
The following class can now be used from Ruby code using convenience shortcuts.
obj = SubscriptingExample.new obj['one'] = 1 puts obj['one'] ...
Performance Improvements
As you could see from the release notes our goal of improving the overall performance of RubyMotion apps is continuing steadily.
Runtime primitives (such as the method dispatcher) are faster by 25%. Builtin classes methods have also been optimized, sometimes by a 2x factor. Some of our users reported very positive feedback from their testers.
As mentioned in our previous report, we are still working on a benchmark suite for RubyMotion. Its goal is to let us identify performance problems as well as catching performance regressions. It is still at this time a work in progress and we still intend to publish it once it's complete.
Jim Weirich
Jim was one of the very early RubyMotion users. He believed in the project and gave us the motivation we needed to keep working on it and launch it.
As the author of Rake, it goes without saying that RubyMotion would not exist without him.
You can watch Jim speaking about RubyMotion at the local Cincinnati Cocoa user group. In this video, Jim demonstrates his legendary joie de vivre as well as his excellent teaching skills.
You can also check out Jim teaching the use of source code control (you do use SCC on your RubyMotion apps, right?) for the Pragmatic Programmers, who have kindly agreed to donate the full proceeds of the screencast to Jim’s family.
Jim passed away the 19th February 2014. He will be deeply missed. Rest in peace, Jim.
RubyMotion Success Story: Jimdo
Jimdo is a web site creation and hosting service based in Hamburg, Germany since 2007. Their motto is Pages to the People! and since last year they provide an iOS app for iPhone and iPad that integrates with their service.
The app was recognized as Best of 2013 by Apple and is fully developed with RubyMotion! We sat down with Christoffer Tews, one of the folks at Jimdo responsible for the app.
Can you tell us a bit about you?
My name is Christoffer Tews. I started at Jimdo ~2 years ago with a student job during my Master of Science in eCommerce . I wanted to do something in the mobile development because my bachelor thesis had been about implementing an iOS shopping app with Appcelerator Titanium and the whole mobile development is just exciting.
So I came to Jimdo and started to work as a student on the very first day on the iOS app of Jimdo with Mark Frawley (Developer) and Jan Schlie (Designer). The team grows up to 10 people later. While doing my masters thesis (building a usability framework for iOS) I decided to join Jimdo as a full time employee, because I loved the product especially the iOS app and the dev team around it. And I still freaking love it! ;)
What is Jimdo the company?
Jimdo is the easiest way to create a website. With a simple, intuitive interface, Jimdo enables anyone to create a unique website with a blog and online store. Our motto—Pages to the People!—sums up our mission: Put the power of website creation into everyone's hands. Whether you want to start a business, promote your music, or simply share photos with your friends and family, you can create your home on the web with Jimdo.
Since it was founded in Hamburg in 2007 by young entrepreneurs Christian Springub, Fridtjof Detzner, and Matthias Henze, Jimdo has grown tremendously. We've helped people build more than 10 million websites and Jimdo is now available in 12 languages. Our team of 170 people come from 15 different countries and work in 4 offices worldwide.
If you want to know how much fun it is to work at Jimdo just look at this page.
What did you make with RubyMotion?
Our iOS app allows users to build a complete webpage for themselves or their business on directly from their mobile device. It’s not like other apps, where you can just edit some parts of your website and maybe don’t even see your site because of a „special user interface“ to edit the content.
With the iOS app of Jimdo you can edit the website simply by touching an element on your website e.g. a headline, some text. You can also structure your entire site’s content with our simple, gesture-driven in-app navigation editor.
What role does the Jimdo iOS app play in your business, and related to that: why did you decide to build the app?
So from the business point of view it has two primary goals. First, it is a value-added service to the existing Jimdo web service, allowing our users to easily update their site with rich media and text while away from their desktop. Secondly it serves as a new platform for organic discovery of our brand, a way for new and different demographics to discover us. We offer the iOS app for free - it doesn’t matter if you are using the Jimdo Free package or the Pro/Business package. The only difference between the packages is, that Pro or Business users will get some extra features in the app that are not available for Jimdo Free users, e.g. Statistics (page views, visitors, etc.), extended Shop features etc. These extra services will grow with the time and we will also always enhance the core app features for Free users to stay true to our core value Pages To The People!.
Given your experience using Appcelerator Titanium, why did your team choose RubyMotion to build the Jimdo app?
So we must admit that we chose Titanium Appcelerator in the beginning (before RubyMotion was released), because Jimdo is a web product with lots of front end web development experience and it seemed a good choice to build a cross-platform app which we could re-use instead of building a native app for just one platform.
However, after about 2 months we regretted choosing Titanium. It was sometimes slow, not very flexible (there were issues customizing TableViewCells and other native UIKit components without writing Objective-C). The support for newer iOS SDK features always lagged months behind Apple releases, and so it impeded our ability to quickly new version-specific features. In short it became clear that building a high- performance app with a huge amount of (UI)-customization wasn't clearly feasible with Titanium.
Apart from that, developing a complex hybrid app with Javascript was clearly no fun at all. In particular, some things that bothered us were: Lack of proper namespaces, classes, accidental global declaration, minor syntax errors passing without warning, undefined variables discovered at runtime etc.
After a new evaluation of possible alternatives we found the freshly distributed RubyMotion framework. We were a little bit afraid of choosing a brand new framework especially because we wasted 2 month of development at this point, but it’s implementation of the Ruby language is directly based on the Cocoa APIs and data types. Therefore, and because it is compiled ahead of time, it’s performance is much closer to standard Objective-C. Also, the possibility to vendor in Objective-C (3rd party) libraries with one line of code, was and is, just awesome. Also at this point ARC wasn't completely released yet and the built-in garbage collection from RubyMotion made our code very terse in comparison to Objective-C.
Even our UI-Designer started to write code. We built our UI without using Storyboard, our entire UI is built with a mix of reusable procedural code and Teacup stylesheets.
What technologies from iOS did you use, and did you have any issue accessing those in RubyMotion?
That is kind of a tough question, because we really use the whole spectrum of iOS technologies. I think there is almost no UI element that we haven’t implemented and customized in our app.
We make heavy use of RubyMotion’s excellent support for Objective-C Categories, which makes implementing delegate protocols very simple. In terms of Apple Frameworks, we use CoreData for non-sensitive data, and Keychain Services to save sensitive data securely on the phone. We also completely redesigned our app to adhere to iOS 7 design guidelines, which includes blurred background images, transparency, flat UI where it makes sense.
We’d like to extend our thanks to the RubyMotion team here for supporting the iOS 7 APIs since its beta stages and for the constant (weekly) updates to fix bugs. We only faced limitations when we tried to (ab)use the Runtime class of Objective-C for meta=programming patterns like method swizzling but this could be solved by writing our own wrapper in Obj-C and vendor it in.
Apart from that we really weren’t confronted with many bugs in RubyMotion and even when there were, our mails and pull requests were answered promptly and the fixes were usually implemented in the next weekly update. We wonder if Laurent gets much sleep because his response time answering emails was never longer than 15 minutes whatever time it was ;) Thanks for that!
What gems, CocoaPods, and other libraries did you use, and which did you find the most useful?
First of all: Teacup! It is just great for designing the UI, decouple the code from the views or controllers and makes it easy to customize elements for different iOS versions.
And we use the following Pods and libraries: SSKeychain, AFNetworking, AdjustIO, Thrift, Crittercism, Reachability, Google Analytics, and much more...
What did you learn from writing this app in RubyMotion that you will remember the next time you need to write an app?
We had a lot of learnings there. Some were about code quality and trying to use patterns like MVC correctly in Cocoa. Others were about how to create useful, maintainable automated tests. We decided very early to establish automated tests but our focus was more on Acceptance Tests written in Cucumber format with the Frank Framework. This was and is still a good solution to our needs but an actual test run take almost 1 hour.
So we decided to increase our unit test coverage with the inbuilt “rake spec” MacBacon framework that ships with RubyMotion. These tests of which we have several hundred already only take a couple of seconds to execute which gives us more immediate feedback.
One of our learnings so far is, start writing unit tests for your iOS app as soon as possible and as much as possible - it really makes you think about your class/module interfaces and encourages you to decouple views, controllers and methods so as to be more testable. It just makes your code better and more solid. You also don’t start to panic on your next upcoming release, if there’s a bug, because you can just test it.
Would you recommend RubyMotion to other developers who are going to start learning iOS app development?
Definitely yes! As mentioned in the intro, we started of with 3 people on the mobile team. All 3 of us hadn’t much experience with Obj-C or Ruby. RubyMotion empowered us to learn both in a very short time. Learning Ruby is quite easy, even combined with learning the iOS Cocoa APIs, it has a flatter learning curve than adding Objective-C into the mix.
From my personal point of view I would even say if you want to learn writing native iOS apps, RubyMotion is the fastest, most technically solid way to do it. I personally also recommend it to academic courses which are usually of a 2-3 month duration (one semester) - a period where it’s hard to additionally learn Obj-C and write a good working prototype in parallel.
When you needed to find out an answer to a tricky problem, how did you get the help and answers you needed?
The support at the RubyMotion Google Group is really good and the response time there is also fast (max. 12h until first response). As some of us had already met Laurent at the BubbleConf in Amsterdam, we just sent him emails directly, but we try to do it only when it really gets technically deep into the RubyMotion implementation or if we have found some curious bugs. I’m pretty sure he thinks “Arrr! This Jimdo dudes again” ;), but as mentioned, his responses were fast and he’s still polite. He doesn’t send standard phrases like “Please open a support ticket at…”, even if maybe he should sometimes to stay sane. Also Colin is really active and helpful in the Google Group.
For a company of this small size, with what I imagine is a huge customer base, HipByte is really responsive. Thanks again for that!
Announcing RubyMotion #inspect 2014
We are super excited to announce our second annual developer conference, #inspect 2014. The event will happen on May 28th and 29th, in lovely San Francisco, California, and is co-organized with our friends at InfiniteRed.
RubyMotion #inspect is our official conference. It is organized for and by the RubyMotion community and aims at covering all the technologies that surround the RubyMotion ecosystem. This is the place where RubyMotion enthusiasts can finally meet face-to-face to chat, connect, hack together and learn what’s happening in the community.
Last year #inspect was organized in Brussels, Belgium. We definitely had a blast. Many guests told us it was the best conference they ever attended. This year we will change a few things and try to innovate with the conference format.
We booked an awesome venue for the event, Fort Mason, a National Historic Landmark right in the Marina district of San Francisco. We will be scheduling at least 16 talks as well as workshops, informal panels, and more activities. Like last year, we will also deliver awesome food and celebrate the end of the event with a great party.
We already pre-selected 8 awesome speakers. If you would like to speak at the conference we definitely want to hear from you.
Early-bird tickets are available, at 25% off the regular admission price, in limited quantity. Don't wait too long. Like last year, the conference is designed to be small and intimate, and will likely sell out before the event.
To those interested, we will also be running a 2-day training right before the conference. It will be a shorter version of our official training program and will be delivered by core RubyMotion engineers. We conveniently provide a Training+Conference ticket.
Finally, we are looking for a small number of sponsors to share in the support of #inspect 2014. This is a great opportunity to show your commitment to the RubyMotion community and also promote your products or services. If you or your company are interested get in touch.
We will be posting more information about the event very soon. Stay tuned and see you in San Francisco!
New in RubyMotion: Device Crash Reports, Pretty Vendor Build Output, Proc#weak!, Performance
Our last release of the year, featuring a few major changes. Let's dive in!
Device Crash Reports
It is an unfortunate reality that applications crash. This is even more so the case during development cycles.
Until today, the best way to deal with device crash reports during development was to use the Xcode organizer. As a lot of you already know, the user experience was far from ideal and symbolication did not always work as expected.
As of RubyMotion 2.18 we are happy to introduce a long-awaited Rake task to deal with device crash reports: rake crashlog:device.
The task will:
Connect to your development device
Retrieve all crash reports generated by your app
Symbolicate them using the .dSYM bundle created by our build system
Save the final reports on your file system
Open the last generated report in Console.app
Let us show you an example. We create a new RubyMotion project and slightly change the application delegate method to trigger one of those UIKit-level exceptions which will crash the process hard.
class AppDelegate def application(application, didFinishLaunchingWithOptions:launchOptions) NSArray.arrayWithArray(42) end end
As expected, running the app on the device causes a crash.
$ rake device [...] Deploy ./build/iPhoneOS-7.0-Development/foo.ipa *** Application is running on the device, use ^C to quit. Dec 29 21:01:49 foo[936] : -[__NSCFNumber count]: unrecognized selector sent to instance 0x17da1190 Dec 29 21:01:49 foo[936] : *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber count]: unrecognized selector sent to instance 0x17da1190'
Since this is a lower-level exception happening on the device the terminal output does not contain its full backtrace. We could easily get it by connecting a debugger, but let's use another way! Since the application crashes a report was generated on the device. We can use the new rake crashlog:device to retrieve that report and see what happened.
$ rake crashlog:device New crash report: /Users/lrz/Library/Logs/RubyMotion Device/foo_2013-12-29-210200_lrzs-iPhone.crash
The command saved a new crash report file and opened it in Console.app. This is what we can see (some of the lines have been trimmed out for better readability):
Last Exception Backtrace: 0 CoreFoundation 0x2f013e7e __exceptionPreprocess + 126 1 libobjc.A.dylib 0x393706c2 objc_exception_throw + 34 2 CoreFoundation 0x2f0177b2 -[NSObject(NSObject) doesNotRecognizeSelector:] + 198 3 CoreFoundation 0x2f0160aa ___forwarding___ + 702 4 CoreFoundation 0x2ef64dc4 __forwarding_prep_0___ + 20 5 CoreFoundation 0x2ef4d70c +[NSArray arrayWithArray:] + 40 [...] 9 foo 0x00097008 rb_scope__application:didFinishLaunchingWithOptions:__ (app_delegate.rb:3) [...]
As we can see, the last frame from our application (highlighted here) in this exception backtrace was in the app_delegate.rb file, line 3, which coincides perfectly with our wrong arrayWithArray: call.
Just by typing one command in the terminal we were able to determine what went wrong on the device. Pretty cool, isn't it?
Pretty Vendor Build Output
The RubyMotion build system invokes the xcodebuild tool in order to build Xcode-based projects. If your project uses CocoaPods or manually vendors Xcode-based libraries you already know that the build terminal output can be messy sometimes.
As of RubyMotion 2.18 the build output of Xcode-based projects will be consistent with the rest of the build. Here is an example of the new output of a project that uses CocoaPods.
Build ./vendor/Pods/Pods.xcodeproj [SORelativeDateTransformer - Release] Compile ./vendor/Pods/Pods-SORelativeDateTransformer-dummy.m Compile ./vendor/Pods/SORelativeDateTransformer/SORelativeDateTransformer/ SORelativeDateTransformer.m Link ./vendor/Pods/.build/libPods-SORelativeDateTransformer.a Build ./vendor/Pods/Pods.xcodeproj [Pods - Release] Compile ./vendor/Pods/Pods-dummy.m Link ./vendor/Pods/.build/libPods.a
This feature would not have been possible without integrating the awesome XCPretty project, created by Marin Usalj and Delisa Mason.
Proc#weak!
Since RubyMotion relies entirely on the underlying iOS' retain count memory model, creating cyclic references is unfortunately possible.
In order to help developers avoid the creation of retain cycles, in the past we introduced the WeakRef class which can be used to create weak-references in Ruby and also a cycle detector that can resolve basic cyclic references at runtime.
Sadly it was still possible to easily create cyclic references using blocks. Let us explain why.
A block in RubyMotion keep a strong reference to the object it was created from, bound as self, which prevents said object from being destroyed before the block can send messages to it.
class Test def foo lambda { bar } end def bar p :here end end o = Test.new b = o.foo o = nil b.call
In this case, the Test object will remain alive until the Proc object dies.
This behavior has the side effect of easily creating cyclic references.
class MyController < UIViewController def viewDidLoad @b = lambda {} end end
In the snippet above, the Proc object keeps a reference to the MyController object, and vice-versa, resulting in a cyclic reference. Because the cyclic detector is at this point not able to detect cycles outside autorelease pool contexts, both objects will leak.
This is where Proc#weak! can come handy. This method makes sure the given Proc object does not keep a strong reference to its self binding anymore.
The method always returns a reference to the receiver and can be safely called multiple times. The snippet above can be rewritten to prevent a cycle:
class MyController < UIViewController def viewDidLoad @b = lambda {}.weak! end end
Now, MyController will still keep a strong reference to our Proc object, but the later will not. MyController can then be safely destroyed when it is no longer needed, along with the Proc object.
We believe that the addition of Proc#weak! was the last remaining piece to help RubyMotion developers prevent cycles in their apps. Some popular libraries (such as BubbleWrap) and high-profile apps (such as Bandcamp) are already successfully using it.
Performance
As you might have already seen from the previous build release notes, we have been working on performance improvements for the past few weeks.
We have been internally building an intensive performance suite. Our objective is to run it periodically against previous versions of RubyMotion in order to catch performance regressions. We are also running the suite against CRuby 2.0 with the goal of providing better performance results in every possible scenario.
This is a long process and we are not done yet, but we will publish the suite and the data online as soon as we have something we are pleased with.
In the meantime, if your app or library is experiencing performance issues, please let us know via a support ticket, attach some code and we will add it to the suite!
RubyMotion Success Story: Bandcamp
Bandcamp is an online music store, as well as a platform for artist promotion, that caters mainly to independent artists. Artists on Bandcamp have a customizable microsite with the albums they upload. All tracks can be played for free on the website and some artists offer free music downloads.
Bandcamp recently launched their new iPhone application and it has been written with RubyMotion. We sat down with Daniel Dickison to talk about his recent experience using Ruby to build an iOS app.
So Daniel, you're at Bandcamp, what's your role over there?
I am a programmer and sort of, the way we do things is all the engineers do a little bit of everything. We're not too specialized, but obviously I've been working on the mobile app, so that's been my thing for the better part of this year.
It's been a solo endeavor?
Mostly, although definitely wasn't totally solo. We have two dedicated designers on the team. So the designers did the design and I did most of the coding. Though a couple other people helped out during the process.
Tell me a little about Bandcamp, what kind of a company is it?
We do music. It's a music platform for mainly independent artists and also labels. So it's a platform for people to put their music up and distribute it and get paid directly from fans for buying music. That's sort of the main thing we do.
Is it a pretty big startup?
I don't have much of a sense of whether we're big relatively. I don't have much of a context. Let's see I think we're something about 15 employees now. We just celebrated our 5th anniversary, 5th birthday of Bandcamp was just a couple weeks ago, so we had a special blog post.
That's right! With very cool ASCII art.
Oh yeah that's Moni, our designer, he's the ASCII art master.
Oh very cool!
He does a lot of ASCII art stuff in the group IRC that we're always on.
It's one of those things you'd expect to be a lost art, and instead it proliferates.
Mmhmm. It's kinda fun, I don't know how people make those, but I'm always impressed when it's animated.
I'm wondering more about the "Bandcamp platform". Is that to say that people build applications using your platform, or is it that you can build multiple applications with?
Oh I meant platform, not in the technical sense, but as artists using the site to promote their own music. We don't set prices, artists basically control their own Bandcamp page. They can give music away for free, or for pay, name your price is like "the big thing" these days.
So the web application has been around for five years?
Yes, that's basically what it was, exclusively, until the app. And the app itself is a compliment to the site.
What led to the mobile app? What was lacking?
There's really, the one big thing was, when fans buy music on Bandcamp, before the app, you would basically get a download for the music, whether it's a track or an album. If you wanted to listen to it on your phone you would have to download it on your computer, then load it onto itunes, then sync that to your iphone, which works, but is 5 steps more than we want people to have to do just to listen to what they bought on their phone.
So the big idea is if you buy something on the site, then you should be able to seamlessly listen to it on your phone, which is the first and main problem that we wanted to solve on the app.
Gotcha, so you wanted a way to download directly to the device and play it, pretty much be one action.
Yup!
What led to the decision to use RubyMotion for the iOS app?
That's an interesting story! So the site's written almost all in Ruby, on the server side, so all the engineers here know Ruby. Personally I've done some iOS development, so I would have gone with Objective-C and written it that way, but Joe, who is head of engineering, I think he was familiar with MacRuby from before, so he heard about RubyMotion and suggested it, and the big plus is that it's a lot easier for other engineers to jump on the project. It's a different API but the language is what we're all used to doing on the server side already. So really that's the big reason.
Has anyone else reviewed your iOS code?
Yeah, so actually after v1 went out, we're working on new features, we actually have another guy that's doing iOS stuff almost full time now for features, and Joe was another one who spent a good chunk of time working on the iOS app.
How was it, introducing them to the organization of the code, and where things go, what was that learning curve like for them, for the new developer?
I'd say, there's still a learning curve, because the UIKit stuff, it's a pretty big API to wrap your head around, but it definitely seems like it's a lot easier to add new features. We look through the code and the syntax is all straight up Ruby.
So the language isn't getting in the way.
Yeah, kind of an interesting aside, back when we were still prototyping the app, I had an idea to do the UI as a Web view. If that had panned out, it would've been really cool because the backend code would've been all Ruby without a lot of the UIKit layers. It would've been very straight up server type code on the backend with Ruby, and the frontend would've been HTML/Javascript. We didn't end up going that way in the end, because it worked pretty well, especially on iOS, it works really well, but it didn't work that well on Android. You lose most of the gains of doing it cross-platform anyways.
Gotcha. Let's talk more about early prototyping. Were you able to use RubyMotion to your advantage there?
I think so, a lot of simple things get really simple. I'm thinking the basic whether you're matching regular expressions with strings, or iterating your arrays or working with hashes, that stuff is so much less verbose, doing it in RubyMotion. And the other, I guess it's both a pro and con, is not having to work in Xcode. I use Sublime Text myself, but it's nice being able to drop right in to the editor you already have customized and not having to have this gigantic IDE. Although, it's not so bad and definitely getting better.
Actually for a while I was using Sublime Text and switching to Xcode to compile, I would switch back and forth. But it is a difference. For me, Xcode doesn't become part of my work flow as well. I can integrate iterm and Sublime Text, I can have them talk to each other very easily.
I feel like if you want to use Xcode to the full extent, you have to let Xcode be the world. Use storyboards, do everything in Xcode because everything's integrated well.
What kind of RubyMotion tools were helpful, like what's your workflow look like?
We didn't use a lot of CocoaPods or anything like that, this was a decision I made early on, because I'm familiar with Ruby and I'm familiar with UIKit and Foundation and all that, a lot of the nice Ruby wrappers I just wanted to write myself, just for maintainability, because you guys are iterating pretty quickly, and iOS SDK's change, not as drastically but you do kinda have to stay on your toes to keep up to date with new APIs that come out, and get deprecated. So it seemed like it might be a good idea just to do it all in our own custom code that we have a good understanding of and can easily change if we need to update it for various things.
My workflow is basically a terminal window open that's firing off rake every time I need to compile, and a Sublime Text window and Dash is awesome for documentation because when you don't have the Xcode, I dunno what you call it, the assistant window, and option-click to get documentation, it's super super useful to have Dash.
I would agree that's the thing that I would love to see implemented, is autocompletion. I guess RubyMine has a very good one but I haven't seen one for Sublime Text. I don't know how'd you do that anyway, that analysis.
Yeah, maybe this exists already but it's probably possible to just hook up a key binding to take whatever string your cursor's currently in and hand that off to Dash. Which I should probably look into, that would be pretty useful.
What I would love is if I started to type UIControl and then I could choose StateNormal, and it would flow off my fingers. Though, for that specific example I use SugarCube of course, it has helpers for that.
I noticed recently that the Sublime Text plugin for RubyMotion recently updated for Sublime Text 3, I haven't installed that yet, I should probably check that out because I think a lot of it would just be having autocompletion for a lot of the constants.
Do you use any gems or CocoaPods?
No we don't actually, we do use some third party libraries, which are pure Objective-C. FMDB is Objective-C wrapper around Sqlite, and Reachability wrapper, just real simple Objective-C stuff. We wrote some Objective-C ourselves. There's a few parts, there's an audio player, one of the main features we have, that we wanted, is to play a track we just bought, streaming, from the server, but we also wanted it to be cached for subsequent plays. It turns out you can't do that with the built-in AVPlayer API. It'll stream, but it won't give you the data to cache it at the same time. So we wrote a little audio player, using the audio queue API. So that's a C API. It may have been possible doing it in Ruby, but it was just easier just to drop into pure Objective-C and C. So we have that.
You expose that with Objective-C classes?
Yeah it's basically an Objective-C wrapper around the C API. It basically takes a file and we can play audio from a file as it's being written out from the server. So that's a low level thing we had to write in Objective-C.
Another thing that RubyMotion contributes to is the ability to organize code differently than you would in Objective-C, I wondered if you had any thoughts on that.
Yeah, actually that's kind of interesting, I hadn't thought too much about it... not having .h files for everything is quicker when you're writing code, you can just start pounding out code without having to switch back and forth, making sure your header and your exposed APIs, and worrying about that stuff. So it's definitely faster, I think.
Any other metaprogramming techniques that you rely on?
Oh yeah let's see, I think there were some. There's some utility base classes that, depending on whether TestFlight SDK is defined or not, if it isn't it'll stub it out with a dummy class that pretends like TestFlight SDK is there. There's definitely little funky Ruby meta-programming stuff that we can do that we throw in there.
Were there any issues with RubyMotion things that hung you up?
There's definitely one thing that was a huge time sink which was the memory management, especially with blocks and multi threading. I filed some bugs with you guys about this, and a lot of it got sorted out.
Any feature requests, things you'd like to see, in terms of RubyMotion?
Let's see... that's a good question I mean the profiling one would have been a huge one but you guys got it already, that would've been one. You know it's actually pretty solid. I think once you guys get this retain cycle and memory management stuff solid, I think that would make it, without question a solid platform to develop in.
Great! Any questions for our side?
I'm curious, are you guys a distributed team?
Yeah we're all over! I'm in Denver, I pretty much step in for the interviews, for community projects, kind of poke around the mailing list as much as I can. Most of the team is in Europe, though we've got Watson in Japan, in Tokyo. So he and Laurent have been the main, core developers, though Eloy Duran is also entered into that world.
We're also distributed, it's interesting to hear about other teams that do that. We do a daily Google Hangout meeting to give status, to keep up to date, I was wondering if you do stuff like that?
Nothing so formal, we are always in HipChat, and it's actually kinda fun because the sun never sets on the HipByte chat, because it transfers from Japan to America to Europe, and there's this perfect 8 hour difference between each one, it just depends on who's awake. There's always at least one person to hand it off.
I think we're pretty close to that! We have a guy in Australia who keeps the lights on when everyone else is out, and then a guy in Oxford, and the rest of us are scattered around the Americas. It's pretty good for us, too, because if there is an emergency, there's usually someone around there's usually someone around to take care of it.
We don't get to take advantage of that, there's usually not compiler emergencies, like there is on the web.
Haha emergencies accumulate a little more slowly.
A little, yeah, and you can always fall back to a previous compiler version, usually that resolves it for the short term. Well Daniel I don't have any more questions for you, I really appreciate you taking this time. And I hope you continue to make apps using RubyMotion.
Oh yeah we're in it for the long haul with this app. You'll definitely hear from us, I'm sure.
Great, congratulations again on shipping!
Thanks! Have a good one!
New RubyMotion Screencasts: MotionInMotion
(This is a guest post from Jack Watson-Hamblin (aka @FluffyJack), creator of MotionInMotion.)
MotionInMotion is launching very soon, and will be one of the screencasts of choice for many to expand their skills and keep them up to date.
I've been working away at getting ready to launch this as a new regularly released screencast for RubyMotion. To make sure I was creating good content you would be interested in, I got together 20 people for an early access group, and I've been getting great feedback from them as they've enjoyed the screencasts.
I’ve put together a pre-launch episode about Nick Quaranto’s motion-layout wrapper, and how I use it to take control of Auto Layout and quickly get it working in my iOS apps.
Everyone that sign’s up to the launch list on the coming soon page, will get a 20% lifetime discount on their subscription when they subscribe in the first week after launch.
Enjoy!