30

RubyMotion Cookbook

Embed Size (px)

DESCRIPTION

Uploaded from Google Docs

Citation preview

Page 1: RubyMotion Cookbook
Page 2: RubyMotion Cookbook

RubyMotion Cookbook

RubyMotion is a commercial iOS development platform using ruby, which adheres to apple appstorespecification it is built by Laurent Sansonetti . In RubyMotion Cookbook I will present solutions for commontasks for building iOS apps, this is based on code published on open source projects, tutorials, porting nativeapps to RubyMotion. You can post your questions / problems / suggestions / sample code / corrections on thislink given below I would try to get a solution and also add it to this book and the accompanying code. Everycontribution would be attributed.

https://github.com/railsfactory/rubymotion-cookbook/issues

RubyMotion Cookbook 1

Page 3: RubyMotion Cookbook

Installation

I am assuming you already have a mac with OSX Lion and App Store installed.

Open the app store, search for xcode, click on it, it is a free app , download it.

Xcode Install

This is a huge file about 1.5GB, so you need to a good connection and have enough time to download in asingle stretch. Make sure you have couple of GB's of free space.

Xcode gets installed in /Developer in your hard disk/SSD.

For running the app built by you on device you would need a Apple developer account, I would add theinstructions at a later time.

RubyMotion install

Ruby comes preinstalled in OSX Lion, open terminal and check the version.

$ ruby -v

ruby 1.8.7 (2010-01-10 patchlevel 249) [universal-darwin11.0]

If you are a advanced user you can get RVM and install a custom ruby version.

Goto RubyMotion site and click on the buy link and buy your RubyMotion License.

Rates as on 9th May is 149$ it is a early bird rate so hurry.

Download the installer http://www.rubymotion.com/files/RubyMotion%20Installer.zip .

Please have your license code ready as it asks at this stage.

Open the zip file and run the installer.

Accept the terms and conditions, enter the license key and begin install, you would be prompted for yoursystem password, once that is done in couple of seconds the install would complete and you are ready to workwith RubyMotion.

Installation 2

Page 4: RubyMotion Cookbook

Getting Started

Your Mac is ready to run RubyMotion, but it is a good idea to view initial screencasts which make understandthe concepts in a visual way

Official intro screencast

(http://www.youtube.com/user/hipbyte)[http://www.youtube.com/user/hipbyte] on this Youtube channel youcan find 2 interesting videos and hope there would be more videos published in coming days.

RubyMotion: Introduction Video 8:51

RubyMotion: Interactive Console Demo 1:09

Interctive Console/REPL is the killer feature which makes it worth diving into RubyMotion.

Pragmatic Studios screencast

http://pragmaticstudio.com/screencasts/rubymotion 50:25

This is a longer version and shows a full cycle of building a app from scratch, self explanatory.

Forum

this is the place to go and find solutions for your problems,

RubyMotion Google Group

Most participants are early adopters, just like you and good discussions happen, please be polite andsomebody would try to help you resolve your issues. Bonus, You can make feature requests as well. Justremember this is a closed/moderated group.

Getting Started 3

Page 5: RubyMotion Cookbook

Build your first app

after seeing the screencasts you would be charged up, now let us begin

Motion command

let us run motion and know what this command can do

$ motion

Usage:

motion [-h, --help]

motion [-v, --version]

motion <command> [<args...>]

Commands:

create Create a new project

activate Activate the software license

update Update the software

support Create a support ticket

Update motion command

RubyMotion is a moving target and it is getting frequent release, I have personally updated from 1.0 to 1.1 ,1.2, 1.3 in less than a week. one thing for sure, Laurent Sansonetti, the RubyMotion author listens to customerfeedback and bug reports and fixes at a astonishing pace. I have tested over 40 apps and crashes have reducedby over 90% between these updates.

$ sudo motion update

$ motion -v

1.3

Hello World

It is obligatory to build a Hello World app in every technology/language

$ motion create hello

Create hello

Create hello/.gitignore

Create hello/Rakefile

Create hello/app

Create hello/app/app_delegate.rb

Create hello/resources

Create hello/spec

Create hello/spec/main_spec.rb

Our project is created and at this stage we can run it on our iOS simulator

$ cd hello

$ rake

Build ./build/iPhoneSimulator-5.0-Development

Compile ./app/app_delegate.rb

Create ./build/iPhoneSimulator-5.0-Development/hello.app

Link ./build/iPhoneSimulator-5.0-Development/hello.app/hello

Create ./build/iPhoneSimulator-5.0-Development/hello.app/Info.plist

Create ./build/iPhoneSimulator-5.0-Development/hello.app/PkgInfo

Create ./build/iPhoneSimulator-5.0-Development/hello.dSYM

Simulate ./build/iPhoneSimulator-5.0-Development/hello.app

Build your first app 4

Page 6: RubyMotion Cookbook

2012-05-10 23:54:08.743 hello[29464:f803] Applications are expected to have a root view controller at the end of application launch

(main)>>

Just ran one command and voila the iOS Simulator is running in iPhone mode and a blank screen is running.Actually your application was compiled, copied to the simulator and executed on the simulator.

Exiting the app

There are three ways

Command + Q when the iOS simulator app is selected and simulator quits, easiest but not intuitive,the app running terminal would break abruptly. Not a nice way for a programmer.

((null))>> $

Ctrl+c interrupts the program immediately.Not a nice way for a programmer.

(main)>> rake aborted! Command failed with status (1): [ /Library/RubyMotion/bin/sim 2 1 5.0"/Dev...]

Tasks: TOP => default => simulator (See full trace by running task with --trace) $

from the terminal type 'exit'

(main)>> exit $

Third way is the recommended version but when app hangs or crashes or erratic behavior you know now howto get out of it.

How it works

now you know the code works, what code boilerplate has been added

WIP

Build your first app 5

Page 7: RubyMotion Cookbook

Let there be Hello World

Let us add some text and display it, one of the simplest to display message is Label or a alert Message, I dontwant to create additional files or config, let us do it in a ruby way, from the RubyMotion console(REPL)

$ rake

Build ./build/iPhoneSimulator-5.0-Development

Simulate ./build/iPhoneSimulator-5.0-Development/hello.app

2012-05-12 08:43:50.545 hello[46454:f803] Applications are expected to have a root view controller at the end of application launch

(main)>> hello = UIAlertView.new

=> #<UIAlertView:0x8dac150>

(main)>> hello.message = "Hello World"

=> "Hello World"

(main)>> hello.show

=> #<UIAlertView:0x8dac150>

Did you see the message is now displayed on your simulator.

Can we change the message to something else, easy

(main)>> hello.message = "Thanks Laurent and Matz"

=> "Thanks Laurent and Matz"

What else can I do

=> hello.methods

=> [:"addTextFieldWithValue:label:", :titleLabel,

:canBecomeFirstResponder, :numberOfRows, :table, :keyboard,

:textField, :"setSubtitle:", :subtitle, :tableView, :dismiss,

:"initWithTitle:buttons:defaultButtonIndex:delegate:context:",

:"setNumberOfRows:", :"popupAlertAnimated:", :"setDimView:",

:"setTitleMaxLineCount:", :"setRunsModal:", :"setBodyText:",

:"setAlertSheetStyle:", :"buttonAtIndex:", :requiresPortraitOrientation,

:textFieldCount, :buttons, :"layoutAnimated:", :"dismissAnimated:",

:"popupAlertAnimated:atOffset:", :"presentSheetFromAboveView:",

:"presentSheetFromBehindView:", :groupsTextFields, :"setGroupsTextFields:",

:"setTaglineText:", :bodyText, :titleMaxLineCount,

:"setBodyTextMaxLineCount:", :bodyMaxLineCount, :"setDefaultButton:",

:defaultButton, :"setDestructiveButton:", :destructiveButton,

:"addButtonWithTitle:label:", :"addButtonWithTitle:buttonClass:",

:buttonCount, :"setTableShouldShowMinimumContent:",

:tableShouldShowMinimumContent, :"setShowsOverSpringBoardAlerts:",

:showsOverSpringBoardAlerts, :isBodyTextTruncated, :"presentSheetInView:",

:"presentSheetToAboveView:", :backgroundSize, :alertSheetStyle,

:"setDimsBackground:", :dimsBackground, :"setSuspendTag:", :suspendTag,

:"setBlocksInteraction:", :blocksInteraction, :runsModal, :titleRect,

:numberOfLinesInTitle, :"presentSheetFromButtonBar:", :"replaceAlert:",

:"popupAlertAnimated:animationType:atOffset:",

:"popupAlertAnimated:animationType:", :"setKeyboardShowsOnPopup:", :bodyTextLabel, :taglineTextLabel, :"setForceHorizontalButtonsLayout:",

:forceHorizontalButtonsLayout, :resignFirstResponder, :becomeFirstResponder,

:layout, :context, :"setContext:",

:"initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:",

:"showWithAnimationType:", :show, :cancelButtonIndex,

:"dismissWithClickedButtonIndex:animated:", :isVisible,

:"addButtonWithTitle:", :"setCancelButtonIndex:", :numberOfButtons,

:"buttonTitleAtIndex:", :"textFieldAtIndex:", :"setMessage:",

:"setDefaultButtonIndex:",

:"initWithTitle:message:delegate:defaultButton:cancelButton:otherButtons:",

:defaultButtonIndex, :firstOtherButtonIndex, :"setAlertViewStyle:",

:alertViewStyle, :dealloc, :"initWithFrame:", :"setTitle:", :title,

:"setDelegate:", :delegate, :message, :"resizeForKeyplaneSize:",

Let there be Hello World 6

Page 8: RubyMotion Cookbook

:"drawRect:forViewPrintFormatter:", :viewPrintFormatter, :textInputView,

:isAccessibilityElementByDefault,

:isElementAccessibilityExposedToInterfaceBuilder,

:textEffectsVisibilityLevel, :textEffectsVisibilityLevelWhenKey,

:"compareTextEffectsOrdering:", :needsWebDocumentViewEventsDirectly,

:"reduceWidth:", :"gestureEnded:", :"setGestureDelegate:",

:"setEnabledGestures:", :"setValue:forGestureAttribute:", :"gestureStarted:",

:"gestureChanged:", :"stateForGestureType:", :"animator:stopAnimation:",

:"animator:startAnimation:", :"zoomToScale:", :"rotateToDegrees:",

:canHandleGestures, :gestureDelegate, :enabledGestures,

:"valueForGestureAttribute:", :"setRotationDegrees:duration:",

:rotationDegrees, :"endEditing:", :useBlockyMagnificationInClassic,

:scriptingInfoWithChildren, :recursiveDescription, :description,

:"layoutSublayersOfLayer:", :"actionForLayer:forKey:",

:"drawLayer:inContext:", :"setValue:forKey:", :gestureRecognizers,

:removeAllGestureRecognizers, :"removeGestureRecognizer:",

:"setGestureRecognizers:", :gesturesEnabled, :"setGesturesEnabled:",

:deliversTouchesForGesturesToSuperview,

:"setDeliversTouchesForGesturesToSuperview:", :"addGestureRecognizer:",

:viewTraversalMark, :isInAnimatedVCTransition, :"setInAnimatedVCTransition:",

:"setViewTraversalMark:", :skipsSubviewEnumeration,

:"setSkipsSubviewEnumeration:", :frameOrigin, :"setFrameOrigin:",

:"pointInside:forEvent:", :"hitTest:forEvent:", :"initWithSize:",

:"setClipsSubviews:", :"createSnapshotWithRect:", :"setEnabled:", :isEnabled,

:"setSize:", :size, :"addAnimation:forKey:",

:"setNeedsDisplayOnBoundsChange:", :"setAlpha:", :"setContentScaleFactor:",

:"setClearsContextBeforeDrawing:", :"setContentMode:", :"setContentStretch:",

:"setClipsToBounds:", :clearsContextBeforeDrawing, :contentMode,

:contentStretch, :clipsToBounds, :contentScaleFactor, :"setClearsContext:",

:recursivelyForceDisplayIfNeeded, :visibleBounds,

:"setFixedBackgroundPattern:", :isHiddenOrHasHiddenAncestor,

:"setContentsPosition:", :"newSnapshotWithRect:", :forceDisplayIfNeeded,

:alpha, :needsDisplay, :needsDisplayOnBoundsChange, :"setBackgroundColor:",

:backgroundColor, :"setHidden:", :isHidden, :"setOpaque:", :isOpaque,

:setNeedsDisplay, :"drawRect:", :"setNeedsDisplayInRect:", :didMoveToWindow,

:layoutSubviews, :"sendSubviewToBack:", :"bringSubviewToFront:",

:"containsView:", :layoutBelowIfNeeded, :"willMoveToWindow:",

:deferredBecomeFirstResponder, :"movedFromSuperview:", :didMoveToSuperview,

:"viewWithTag:", :"insertSubview:atIndex:",

:"exchangeSubviewAtIndex:withSubviewAtIndex:",

:"insertSubview:belowSubview:", :"insertSubview:aboveSubview:",

:"didAddSubview:", :"willMoveToSuperview:", :"insertSubview:below:",

:"insertSubview:above:", :"movedToSuperview:", :"viewWillMoveToSuperview:",

:viewDidMoveToSuperview, :"movedFromWindow:", :"movedToWindow:",

:"isDescendantOfView:", :window, :subviews, :setNeedsLayout, :superview,

:removeFromSuperview, :"willRemoveSubview:", :layoutIfNeeded, :"addSubview:",

:"sizeThatFits:", :"hitTest:withEvent:", :isMultipleTouchEnabled,

:"resizeSubviewsWithOldSize:", :"pointInside:withEvent:",

:"resizeWithOldSuperviewSize:", :autoresizingMask,

:"setMultipleTouchEnabled:", :"setExclusiveTouch:", :isExclusiveTouch,

:"convertSize:toView:", :"convertSize:fromView:", :hitRect,

:"setFrame:forFields:", :"setRotationBy:", :"setAutoresizesSubviews:",

:autoresizesSubviews, :sizeToFit, :origin, :"setOrigin:", :extent,

:"setAutoresizingMask:", :"convertRect:toView:", :"convertRect:fromView:",

:bounds, :transform, :position, :"setFrame:", :"setTransform:",

:"setBounds:", :"convertPoint:fromView:", :"convertPoint:toView:", :frame,

:center, :"setCenter:", :"setPosition:", :"setUserInteractionEnabled:",

:charge, :"setTag:", :isUserInteractionEnabled, :cancelTouchTracking,

:cancelMouseTracking, :tapDelegate, :"setCharge:", :"setTapDelegate:",

:"startHeartbeat:inRunLoopMode:", :"stopHeartbeat:", :canHandleSwipes,

:"swipe:withEvent:", :tag, :init, :layer, :nextResponder, :"initWithCoder:",

:"encodeWithCoder:", :defaultFirstResponder, :nextFirstResponder,

:inputAccessoryView, :inputView, :reloadInputViews,

:reloadInputViewsWithoutReset, :"canPerformAction:withSender:",

Let there be Hello World 7

Page 9: RubyMotion Cookbook

:"touchesCancelled:withEvent:", :"motionEnded:withEvent:",

:"touchesBegan:withEvent:", :"touchesMoved:withEvent:", :"touchesEnded:withEvent:", :"motionBegan:withEvent:",

:"motionCancelled:withEvent:", :"remoteControlReceivedWithEvent:",

:"mouseDragged:", :isFirstResponder, :canResignFirstResponder, :undoManager,

:"mouseDown:", :"mouseExited:", :"mouseEntered:", :"scrollWheel:",

:"mouseMoved:", :"mouseUp:", :firstResponder, :sessions, :help, :quit,

:"repl:", :to_plist, :"Complex:", :Complex, :"Rational:", :Rational,

:"enum_for:", :enum_for, :"to_enum:", :to_enum, :object_id, :__id__,

:"define_singleton_method:", :define_singleton_method, :"public_method:",

:"method:", :"extend:", :extend, :"respond_to_missing?:", :"respond_to?:",

:respond_to?, :"public_send:", :public_send, :"send:", :send, :"__send__:",

:__send__, :"instance_exec:", :instance_exec, :"instance_eval:",

:instance_eval, :__callee__, :__method__, :tap, :"is_a?:", :"kind_of?:",

:"instance_of?:", :"instance_variable_defined?:", :"instance_variable_set:",

:"instance_variable_get:", :instance_variables, :"public_methods:",

:public_methods, :"private_methods:", :private_methods,

:"protected_methods:", :protected_methods, :"singleton_methods:",

:singleton_methods, :"methods:", :methods, :inspect, :to_s, :untrusted?,

:untrust, :trust, :frozen?, :freeze, :untaint, :tainted?, :taint, :__type__,

:dup, :clone, :"<=>:", :"eql?:", :"!~:", :"=~:", :"===:", :nil?, :"!=:", :!,

:"==:", :"equal?:", :selectionAffinity, :defaultAccessibilityTraits,

:"accessibilitySetIdentification:", :"indexOfAccessibilityElement:",

:"accessibilityElementAtIndex:", :accessibilityElementCount,

:accessibilityIncrement, :accessibilityDecrement, :"accessibilityScroll:",

:accessibilityPerformEscape, :accessibilityElementDidBecomeFocused,

:accessibilityElementDidLoseFocus, :accessibilityElementIsFocused,

:accessibilityFrame, :storedAccessibilityViewIsModal,

:storedAccessibilityElementsHidden, :accessibilityHint,

:accessibilityActivationPoint, :accessibilityTraits, :accessibilityLanguage,

:accessibilityIdentifier, :accessibilityViewIsModal,

:accessibilityElementsHidden, :storedAccessibilityTraits,

:storedIsAccessibilityElement, :storedAccessibilityFrame,

:storedAccessibilityActivationPoint, :"setAccessibilityElementsHidden:",

:"setAccessibilityViewIsModal:", :"setAccessibilityHint:",

:"setAccessibilityFrame:", :"setAccessibilityActivationPoint:",

:"setAccessibilityTraits:", :"setIsAccessibilityElement:",

:"setAccessibilityContainer:", :"setAccessibilityLanguage:",

:"setAccessibilityIdentifier:", :accessibilityContainer, :accessibilityLabel,

:"setAccessibilityValue:", :accessibilityValue, :"setAccessibilityLabel:",

:isAccessibilityElement, :awakeFromNib, :classForPortCoder,

:"replacementObjectForPortCoder:", :"methodDescriptionForSelector:",

:"performSelectorOnMainThread:withObject:waitUntilDone:modes:",

:"performSelector:onThread:withObject:waitUntilDone:modes:",

:"performSelectorInBackground:withObject:",

:"performSelector:onThread:withObject:waitUntilDone:",

:"performSelectorOnMainThread:withObject:waitUntilDone:",

:"performSelector:object:afterDelay:",

:"performSelector:withObject:afterDelay:",

:"performSelector:withObject:afterDelay:inModes:",

:autoContentAccessingProxy, :classForCoder, :"replacementObjectForCoder:",

:"awakeAfterUsingCoder:", :"implementsSelector:", :allowsWeakReference,

:retainWeakReference, :classForKeyedArchiver,

:"replacementObjectForKeyedArchiver:", :observationInfo,

:"setObservationInfo:", :"willChange:valuesAtIndexes:forKey:",

:"didChange:valuesAtIndexes:forKey:",

:"willChangeValueForKey:withSetMutation:usingObjects:",

:"didChangeValueForKey:withSetMutation:usingObjects:",

:"didChangeValueForKey:", :"willChangeValueForKey:",

:"removeObserver:forKeyPath:", :"addObserver:forKeyPath:options:context:",

:"removeObserver:forKeyPath:context:",

:"observeValueForKeyPath:ofObject:change:context:",

:"setValuesForKeysWithDictionary:", :"dictionaryWithValuesForKeys:",

:"setNilValueForKey:", :"validateValue:forKeyPath:error:",

:"validateValue:forKey:error:", :"mutableArrayValueForKeyPath:",

Let there be Hello World 8

Page 10: RubyMotion Cookbook

:"mutableArrayValueForKey:", :"mutableOrderedSetValueForKeyPath:",

:"mutableOrderedSetValueForKey:", :"mutableSetValueForKeyPath:",

:"mutableSetValueForKey:", :"setValue:forKeyPath:", :"valueForKeyPath:",

:"valueForUndefinedKey:", :"setValue:forUndefinedKey:", :"valueForKey:",

:"replacementObjectForArchiver:", :classForArchiver, :isNSValue__,

:isNSString__, :isNSNumber__, :isNSArray__, :isNSDictionary__, :isNSData__,

:isNSDate__, :isNSSet__, :isNSOrderedSet__, :isNSTimeZone__,

:"CA_interpolateValues:::interpolator:", :"CA_distanceToValue:",

:"CA_interpolateValue:byFraction:", :"CA_addValue:multipliedBy:",

:CA_copyRenderValue, :CA_prepareRenderValue, :pep_onMainThread,

:"pep_onOperationQueue:priority:",

:"pep_onThread:immediateForMatchingThread:", :"pep_onThread:",

:"pep_getInvocation:", :"pep_onOperationQueue:", :"pep_afterDelay:",

:pep_onDetachedThread, :pep_onMainThreadIfNecessary, :releaseOnMainThread,

:class, :"isEqual:", :hash, :retain, :release, :autorelease, :retainCount,

:copy, :finalize, :"forwardInvocation:", :"isKindOfClass:",

:"respondsToSelector:", :"doesNotRecognizeSelector:", :"performSelector:",

:"performSelector:withObject:", :self, :mutableCopy, :debugDescription,

:"forwardingTargetForSelector:", :"methodSignatureForSelector:", :superclass,

:zone, :"performSelector:withObject:withObject:", :isProxy,

:"isMemberOfClass:", :"conformsToProtocol:", :isFault, :"methodForSelector:"]

(main)>> self.methods.count

464

Thats so much information to handle to understand what these do , iOS API docs on Dash is a better option,but you get what is possible

How do we identify the relevant methods

(main)>> def useful_methods(variable); variable.public_methods.select {|k| k == k.downcase} - " ".methods ; end

So useful_methods is too long change it into something memorable for you, I will define it as "um", I amtyping again as alias method is not available as RubyMotion is still not a 100% ruby implementation

def um(variable); variable.public_methods.select {|k| k == k.downcase} - " ".methods ; end

(main)>> um(hello)

...

(main)>> useful_methods(hello)

=> [:table, :keyboard, :subtitle, :dismiss, :buttons, :layout, :context, :show, :title, :delegate, :message, :alpha, :window, :subviews, :superview, :origin, :extent, :bounds, :transform, :position, :frame, :charge, :tag, :layer]

This is more manageable, what did that magic method do, since RubyMotion is using native Objective-C asprimitive all the methods are visible and they follow camelCase and colon in methods. additionally i haveremoved common methods derived in any string instance.

Let us hide the message from console

(main)>> hello.dismiss

Bring it back

(main)>> hello.show

Let us add a title to the message window

(main)>> hello.title = "Title"

See this is fun.

Let us try few more properties

Let there be Hello World 9

Page 11: RubyMotion Cookbook

(main)>> hello.subtitle = "Subtitle"

(main)>> hello.message = "New Message"

Let us try something else

(main)>> hello.position

=> #<TypeError: unrecognized runtime type `{CGPoint=ff}'

We dont know what parameters are required but nothing big is lost, as the worst that might happen is theconsole crashes, but it is still a rare occasion.

Whatever code works fine on console gets added to your editor and then gets commited to you repository andyou are making progress one line at a time.

Think about doing it on Xcode, each compile would take its time, and would be not the best way to developquickly.

You dont need to perfect code which would run on the first run, you just need to focus on the task in hand

There are more than one way of doing anything in nearly every technology, but when you are learning learnone way of doing it first and go forward, over a period you would be a learnt man and can justify which isbetter as experience teaches you.

WIP

Let there be Hello World 10

Page 12: RubyMotion Cookbook

Read Code

Reading code is the best way to learn programming. I have been daily searching Hacker News , github andRubyMotion group to learn for how RubyMotion works, discover projects, problems faced by other people.

I have tried to automate the process of downloading all the new projects for you to discover on your mac. Ifyou follow the following steps you can checkout over 40 repositories as of now, more would be added incoming days

Clone the RubyMotion Cookbook repository

$ git clone https://github.com/railsfactory/rubymotion-cookbook.git

Cloning into rubymotion-cookbook...

remote: Counting objects: 143, done.

remote: Compressing objects: 100% (88/88), done.

remote: Total 143 (delta 53), reused 115 (delta 28)

Receiving objects: 100% (143/143), 1.11 MiB | 178 KiB/s, done.

Resolving deltas: 100% (53/53), done.

$ cd projects

$ sh clone_all.sh

....

It will take some time as about 100mb is downloaded directly from the repositories.

Projects which is being checked out are

https://github.com/seanho/Currency.git https://github.com/samchandra/Fonts.githttps://github.com/stiller/LOLCatApp.git https://github.com/locousobscura/LastTime-iOS.githttps://github.com/ps2/MotionGL.git https://github.com/caike/MotionHello.githttps://github.com/siuying/NanoStoreInMotion.git https://github.com/rounders/RestKitTest.githttps://github.com/siuying/RubyMotion-PocketCoreImage.githttps://github.com/tnantoka/RubyMotionApps.git https://github.com/HipByte/RubyMotionSamples.githttps://github.com/gpasq/RubyMotionZXingExample.git https://github.com/seanho/SimpleView.githttps://github.com/siuying/SparrowInMotion.git https://github.com/rjowens/TableViewPullRefresh.githttps://github.com/dalacv/WordSearcher.git https://github.com/anydiem/cocosmotion.githttps://github.com/evanphx/distance_between.githttps://github.com/aaronfeng/facebook-auth-ruby-motion-example.githttps://github.com/jamesjn/fast_imgur_emailer-motion-ios.git https://github.com/latompa/griddler.githttps://github.com/thbar/learning-rubymotion.git https://github.com/tvandervossen/motion-webview.githttps://github.com/rjfranco/pragmatic-rubymotion.git https://github.com/clayallsopp/remote_model.githttps://github.com/seanlilmateus/rmdialog.git https://github.com/macfanatic/rmotion.githttps://github.com/ryw/rubymotion-experiments.git https://github.com/benr75/rubymotion-presentation.githttps://github.com/cebartling/rubymotion-spikes.githttps://github.com/MarkVillacampa/rubymotion-tabbar.git https://github.com/hellopatrick/wave.githttps://github.com/spllr/TwitterApp.git https://github.com/siuying/hpple-motion.githttps://github.com/rjowens/SplitViewControllerExample.git https://github.com/eatcpcks/rubymotion-bars.githttps://github.com/malkomalko/motion-layouts.githttps://github.com/sakisakira/IBOutletActionRubyMotion.git https://github.com/nlehuen/MotionCalc.githttps://github.com/Watson1978/RubyMotion-Benchmark.githttps://github.com/mordaroso/rubymotion-keychain-example.git

Read Code 11

Page 13: RubyMotion Cookbook

Reading the code and Running the apps

You can read all the project code in your favorite text editor or IDE, I prefer Textmate. Running individualapp is simple change into the directory and run rake and it compiles and runs.

Running all these apps at a stretch

$ # in projects folder

$ sh run_all.sh

See all the apps running in sequence, in your simulator, stopping app technique one and two might beoccasionally required.

Submit your app for this list

If you want your app be added, removed, please post a ticket

https://github.com/railsfactory/rubymotion-cookbook/issues

Reading Apple iOS API Documentation

Dash is a nice app to read iOS Documentation Mac App Store link

after downloading go to preferences and enable docsets and choose the libraries you would like to read anddownload, but for iOS you would need to download it inside xcode itself. iOS 5 documentation is about500mb but still it is worth if you want to build or debug any non trivial apps

I found this gem from Steven Ringo on RubyMotion Group•

WIP

Read Code 12

Page 14: RubyMotion Cookbook

Best Practices

WIP

Best Practices 13

Page 15: RubyMotion Cookbook

Controllers

WIP

Controllers 14

Page 16: RubyMotion Cookbook

Views

WIP

Views 15

Page 17: RubyMotion Cookbook

TableView

WIP

TableView 16

Page 18: RubyMotion Cookbook

REPL: Interactive Console

WIP

REPL: Interactive Console 17

Page 19: RubyMotion Cookbook

Core Location

WIP

Core Location 18

Page 20: RubyMotion Cookbook

Core Data

WIP

Core Data 19

Page 21: RubyMotion Cookbook

Camera

WIP

Camera 20

Page 22: RubyMotion Cookbook

Audio

WIP

NAME

video

Audio 21

Page 23: RubyMotion Cookbook

Graphics

WIP

Graphics 22

Page 24: RubyMotion Cookbook

Addressbook

WIP

Addressbook 23

Page 25: RubyMotion Cookbook

Core Location

WIP

Core Location 24

Page 26: RubyMotion Cookbook

Cocoapods: using Objective C third partylibraries/frameworks

WIP

Cocoapods: using Objective C third party libraries/frameworks 25

Page 27: RubyMotion Cookbook

Facebook

WIP

Facebook 26

Page 28: RubyMotion Cookbook

Consuming ReSTful API

WIP

Consuming ReSTful API 27

Page 29: RubyMotion Cookbook

TestFlight

WIP

TestFlight 28

Page 30: RubyMotion Cookbook

App Store

WIP

App Store 29