RubyMotion Cookbook
-
Upload
greg-santos -
Category
Documents
-
view
941 -
download
5
description
Transcript of 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
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
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
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
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
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
:"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
:"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
:"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
(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
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
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
Best Practices
WIP
Best Practices 13
Controllers
WIP
Controllers 14
Views
WIP
Views 15
TableView
WIP
TableView 16
REPL: Interactive Console
WIP
REPL: Interactive Console 17
Core Location
WIP
Core Location 18
Core Data
WIP
Core Data 19
Camera
WIP
Camera 20
Audio
WIP
NAME
video
Audio 21
Graphics
WIP
Graphics 22
Addressbook
WIP
Addressbook 23
Core Location
WIP
Core Location 24
Cocoapods: using Objective C third partylibraries/frameworks
WIP
Cocoapods: using Objective C third party libraries/frameworks 25
WIP
Facebook 26
Consuming ReSTful API
WIP
Consuming ReSTful API 27
TestFlight
WIP
TestFlight 28
App Store
WIP
App Store 29