SlideShare une entreprise Scribd logo
1  sur  55
Ignorance is Strength
           or

  How I Learned to Stop
 Worrying About XCode
and Objective-C and Learn
to Love iOS Development
Start
About Me

• Paul Infield-Harm
• Director of Product Development at Cyrus
  Innovation
• http://about.me/pinfieldharm
http://www.cyrusinnovation.com/
About you

• Ruby?
• Objective-C?
• iOS?
• RubyMotion?
What’s the point of this
         talk?
• I decided to try to learn RubyMotion
  without first learning traditional iOS
  development in XCode and Objective-C.
• If you’re starting out, you might be
  wondering how to start.
• A mix of experience report and tips-and-
  tricks
• This is also just about learning something
  new.
A way to learn

• Understand enough to make something,
  however messy
• Make it smaller
• Introduce third-party code
• Start over
Final Version
The final version
     system
http://markforster.squarespace.com/
Final Version system
•   Keep a list of tasks

•   Mark the first item with a dot

•   Go down the list until you find an item you want
    to do before the closest dotted item above

•   Repeat until you reach the end of the list

•   Then attend to the tasks in bottom-up order

•   Delete completed items, and otherwise move
    items to the end when you stop working on them

•   When nothing is left dotted, start dotting at the
    top again
Example
Write slides for meetup
Prepare TPS report
Get a haircut
Contemplate my mortality
Eat some ice cream
Example

• Write slides for meetup
  Prepare TPS report
• Get a haircut
  Contemplate my mortality
• Eat some ice cream
Example

• Write slides for meetup
  Prepare TPS report
• Get a haircut
  Contemplate my mortality
• Eat some ice cream
fv app
[demo]
RubyMotion
Here’s what some
rubymotion code looks
         like
fv source code

https://github.com/cyrusinnovation/fv
class TaskImageController < UIImagePickerController

  def viewDidLoad
    self.sourceType = has_camera? ? UIImagePickerControllerSourceTypeCamera :
UIImagePickerControllerSourceTypePhotoLibrary
    self.mediaTypes = [KUTTypeImage]
    self.delegate = self
    self.allowsImageEditing = false
  end

  def imagePickerControllerDidCancel(picker)
    presentingViewController.dismissModalViewControllerAnimated(true)
  end

  def imagePickerController(picker, didFinishPickingMediaWithInfo:info)
    mediaType = info[UIImagePickerControllerMediaType]
    TaskList.shared.add_photo_task(info[UIImagePickerControllerOriginalImage])
    presentingViewController.dismissModalViewControllerAnimated(true)
  end

  def has_camera?
    UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceTypeCamera)
  end

end
class TaskList
  TaskListChangedNotification = 'TaskListChanged'

  def self.shared
    @instance ||= TaskList.new
  end

  def all_tasks
    TaskStore.shared.all_tasks
  end

  def add_text_task(text)
    make_change do
      return if text == ''
      TaskStore.shared.create_task do |task|
        task.date_moved = NSDate.date
        task.text = text
        task.dotted = false
        task.active = false
        task.photo = false
      end
    end
  end

  def add_photo_task(image)
    make_change do
      TaskStore.shared.create_task do |task|
        task.date_moved = NSDate.date
        task.dotted = false
        task.active = false
        task.photo = true
        task.photo_uuid = BubbleWrap.create_uuid
        scaled_image = ImageStore.saveImage(image, forTask:task)
What is RubyMotion?

• Ruby re-implemented on top of iOS
• Ruby statically compiled
• Terminal-based toolchain
• Keep using your favorite editor
• Amazing community
(slide stolen from Laurent Sansonetti talk “RubyMotion: Ruby in your pocket” by Laurent Sansonett
                                via http://youtu.be/gG9GTUTI9ys)
How is it different from
         Ruby?
• added named arguments
• no eval
• no define_method
• no require
• most gems don’t work out of the box
Close-reading
Basic idea: Really
understand a working
RubyMotion program
Pierre Menard, Author
         of the Quixote

http://www.coldbacon.com/writing/borges-quixote.html
He did not want to compose another Quixote —which is easy— but the Quixote
itself. Needless to say, he never contemplated a mechanical transcription of the
original; he did not propose to copy it. His admirable intention was to produce a
few pages which would coincide—word for word and line for line—with those of
Miguel de Cervantes.

[...]

The first method he conceived was relatively simple. Know Spanish well, recover
the Catholic faith, fight against the Moors or the Turk, forget the history of Europe
between the years 1602 and 1918, be Miguel de Cervantes. Pierre Menard studied
this procedure (I know he attained a fairly accurate command of seventeenth-
century Spanish) but discarded it as too easy. Rather as impossible! my reader will
say. Granted, but the undertaking was impossible from the very beginning and of all
the impossible ways of carrying it out, this was the least interesting. To be, in the
twentieth century, a popular novelist of the seventeenth seemed to him a
diminution. To be, in some way, Cervantes and reach the Quixote seemed less
arduous to him—and, consequently, less interesting—than to go on being Pierre
Menard and reach the Quixote through the experiences of Pierre Menard.
Close-reading fv
[code]
Apple Developer docs

 http://developer.apple.com/library/IOs
Dash

http://kapeli.com/dash/
rubymotion.com docs

http://www.rubymotion.com/developer-center/
Translation
When you need to
      translate

• Making API calls
• Reading/using sample code
RubyMotion runtime
            guide
http://www.rubymotion.com/developer-center/guides/runtime/
Rewriting example:
 tableview code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"TimeZoneCell";

    TimeZoneCell *timeZoneCell = (TimeZoneCell *)[tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
    if (timeZoneCell == nil) {
        timeZoneCell = [[[TimeZoneCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
        timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT);
    }
    Region *region = [displayList objectAtIndex:indexPath.section];
    NSArray *regionTimeZones = region.timeZoneWrappers;
    [timeZoneCell setTimeZoneWrapper:[regionTimeZones objectAtIndex:indexPath.row]];
    return timeZoneCell;
}




http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/TableView_iPhone/TableViewCells/TableViewCells.html
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"TimeZoneCell";

    TimeZoneCell *timeZoneCell = (TimeZoneCell *)[tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
    if (timeZoneCell == nil) {
        timeZoneCell = [[[TimeZoneCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
        timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT);
    }
    Region *region = [displayList objectAtIndex:indexPath.section];
    NSArray *regionTimeZones = region.timeZoneWrappers;
    [timeZoneCell setTimeZoneWrapper:[regionTimeZones objectAtIndex:indexPath.row]];
    return timeZoneCell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"TimeZoneCell";

    TimeZoneCell *timeZoneCell = (TimeZoneCell *)[tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
    if (timeZoneCell == nil) {
        timeZoneCell = [[[TimeZoneCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
        timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT);
    }
    Region *region = [displayList objectAtIndex:indexPath.section];
    NSArray *regionTimeZones = region.timeZoneWrappers;
    [timeZoneCell setTimeZoneWrapper:[regionTimeZones objectAtIndex:indexPath.row]];
    return timeZoneCell;
}



CellIdentifier = "TimeZoneCell"
def tableView(tableView, cellForRowAtIndexPath:indexPath)
  timeZoneCell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier)
  if (timeZoneCell == nil) {
    timeZoneCell = TimeZoneCell.alloc.initWithStyle(UITableViewCellStyleDefault,
reuseIdentifier:CellIdentifier)
    timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT)
  }
  region = displayList.objectAtIndex(indexPath.section)
  regionTimeZones = region.timeZoneWrappers
  timeZoneCell.setTimeZoneWrapper(regionTimeZones.objectAtIndex(indexPath.row))
  timeZoneCell
end
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"TimeZoneCell";

    TimeZoneCell *timeZoneCell = (TimeZoneCell *)[tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
    if (timeZoneCell == nil) {
        timeZoneCell = [[[TimeZoneCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
        timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT);
    }
    Region *region = [displayList objectAtIndex:indexPath.section];
    NSArray *regionTimeZones = region.timeZoneWrappers;
    [timeZoneCell setTimeZoneWrapper:[regionTimeZones objectAtIndex:indexPath.row]];
    return timeZoneCell;
}



CellIdentifier = "TimeZoneCell"
def tableView(tableView, cellForRowAtIndexPath:indexPath)
  timeZoneCell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) || begin
    timeZoneCell = TimeZoneCell.alloc.initWithStyle(UITableViewCellStyleDefault,
reuseIdentifier:CellIdentifier)
    timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT)
    timeZoneCell
  end
  region = displayList[indexPath.section]
  regionTimeZones = region.timeZoneWrappers
  timeZoneCell.timeZoneWrapper = regionTimeZones[indexPath.row]
  timeZoneCell
end
About 30% reduction in
  code size, without
  much Rubification
This is as much
Objective-C as I
needed to know
Wrapper libraries
BubbleWrap
A collection of (tested) helpers and wrappers used to wrap
   CocoaTouch code and provide more Ruby like APIs.


                 http://bubblewrap.io/
addGestureRecognizer(UITapGestureRecognizer.alloc.initWithTarget(self, action:"handleTap"))
addGestureRecognizer(UISwipeGestureRecognizer.alloc.initWithTarget(self, action:"handleRightSwipe"))
leftRecognizer = UISwipeGestureRecognizer.alloc.initWithTarget(self, action:"handleLeftSwipe")
leftRecognizer.direction = UISwipeGestureRecognizerDirectionLeft
addGestureRecognizer(leftRecognizer)


def handleTap
  TaskList.shared.toggle_dotted(taskID)
end

def handleRightSwipe
  TaskList.shared.remove_task(taskID) if @active
end

def handleLeftSwipe
  TaskList.shared.pause_task(taskID) if @active
end


                                          Before
              when_tapped { TaskList.shared.toggle_dotted(taskID) }
              when_swiped_right { TaskList.shared.remove_task(taskID) if @active }
              when_swiped_left { TaskList.shared.pause_task(taskID) if @active }



                                          After
sugarcube
a small library of extensions to the Ruby built-in classes that make it
a little easier - and hopefully more “rubyesque” - to work in Cocoa.



          https://github.com/rubymotion/sugarcube
Using other people’s
 objective-c code
Using third-party
        libraries

• vendoring
• cocoapods
Finding ios libraries

 http://www.cocoacontrols.com/
cocoapods
(go ye with caution)

http://cocoapods.org/
Getting help
Find someone who
knows more than you
RubyMotion Google
      Group

http://groups.google.com/group/rubymotion
Stack Overflow
My office hours

http://ohours.org/pinfieldharm
Thanks

http://www.slideshare.net/pinfieldharm/rubymotion-talk

Contenu connexe

Similaire à Rubymotion talk

Refactor your way forward
Refactor your way forwardRefactor your way forward
Refactor your way forwardJorge Ortiz
 
Implementing new WebAPIs
Implementing new WebAPIsImplementing new WebAPIs
Implementing new WebAPIsJulian Viereck
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.jsChris Cowan
 
iPhone dev intro
iPhone dev introiPhone dev intro
iPhone dev introVonbo
 
Beginning to iPhone development
Beginning to iPhone developmentBeginning to iPhone development
Beginning to iPhone developmentVonbo
 
RubyMotion
RubyMotionRubyMotion
RubyMotionMark
 
MFF UK - Introduction to iOS
MFF UK - Introduction to iOSMFF UK - Introduction to iOS
MFF UK - Introduction to iOSPetr Dvorak
 
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...Docker, Inc.
 
iPhone Camp Birmingham (Bham) - Intro To iPhone Development
iPhone Camp Birmingham (Bham) - Intro To iPhone DevelopmentiPhone Camp Birmingham (Bham) - Intro To iPhone Development
iPhone Camp Birmingham (Bham) - Intro To iPhone Developmentandriajensen
 
Android UI Development: Tips, Tricks, and Techniques
Android UI Development: Tips, Tricks, and TechniquesAndroid UI Development: Tips, Tricks, and Techniques
Android UI Development: Tips, Tricks, and TechniquesEdgar Gonzalez
 
Android UI Tips, Tricks and Techniques
Android UI Tips, Tricks and TechniquesAndroid UI Tips, Tricks and Techniques
Android UI Tips, Tricks and TechniquesMarakana Inc.
 
Dockercon EU 2014
Dockercon EU 2014Dockercon EU 2014
Dockercon EU 2014Rafe Colton
 
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...Sang Don Kim
 
iOS Development: What's New
iOS Development: What's NewiOS Development: What's New
iOS Development: What's NewNascentDigital
 
I pad uicatalog_lesson02
I pad uicatalog_lesson02I pad uicatalog_lesson02
I pad uicatalog_lesson02Rich Helton
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
MFF UK - Advanced iOS Topics
MFF UK - Advanced iOS TopicsMFF UK - Advanced iOS Topics
MFF UK - Advanced iOS TopicsPetr Dvorak
 

Similaire à Rubymotion talk (20)

Refactor your way forward
Refactor your way forwardRefactor your way forward
Refactor your way forward
 
Implementing new WebAPIs
Implementing new WebAPIsImplementing new WebAPIs
Implementing new WebAPIs
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.js
 
Titanium Alloy Tutorial
Titanium Alloy TutorialTitanium Alloy Tutorial
Titanium Alloy Tutorial
 
React nativebeginner1
React nativebeginner1React nativebeginner1
React nativebeginner1
 
iPhone dev intro
iPhone dev introiPhone dev intro
iPhone dev intro
 
Beginning to iPhone development
Beginning to iPhone developmentBeginning to iPhone development
Beginning to iPhone development
 
RubyMotion
RubyMotionRubyMotion
RubyMotion
 
MFF UK - Introduction to iOS
MFF UK - Introduction to iOSMFF UK - Introduction to iOS
MFF UK - Introduction to iOS
 
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
 
iPhone Camp Birmingham (Bham) - Intro To iPhone Development
iPhone Camp Birmingham (Bham) - Intro To iPhone DevelopmentiPhone Camp Birmingham (Bham) - Intro To iPhone Development
iPhone Camp Birmingham (Bham) - Intro To iPhone Development
 
Android UI Development: Tips, Tricks, and Techniques
Android UI Development: Tips, Tricks, and TechniquesAndroid UI Development: Tips, Tricks, and Techniques
Android UI Development: Tips, Tricks, and Techniques
 
Android UI Tips, Tricks and Techniques
Android UI Tips, Tricks and TechniquesAndroid UI Tips, Tricks and Techniques
Android UI Tips, Tricks and Techniques
 
Dockercon EU 2014
Dockercon EU 2014Dockercon EU 2014
Dockercon EU 2014
 
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
 
iOS Development: What's New
iOS Development: What's NewiOS Development: What's New
iOS Development: What's New
 
I pad uicatalog_lesson02
I pad uicatalog_lesson02I pad uicatalog_lesson02
I pad uicatalog_lesson02
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
What is Node.js
What is Node.jsWhat is Node.js
What is Node.js
 
MFF UK - Advanced iOS Topics
MFF UK - Advanced iOS TopicsMFF UK - Advanced iOS Topics
MFF UK - Advanced iOS Topics
 

Dernier

Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 

Dernier (20)

Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 

Rubymotion talk

  • 1. Ignorance is Strength or How I Learned to Stop Worrying About XCode and Objective-C and Learn to Love iOS Development
  • 3. About Me • Paul Infield-Harm • Director of Product Development at Cyrus Innovation • http://about.me/pinfieldharm
  • 5. About you • Ruby? • Objective-C? • iOS? • RubyMotion?
  • 6. What’s the point of this talk? • I decided to try to learn RubyMotion without first learning traditional iOS development in XCode and Objective-C. • If you’re starting out, you might be wondering how to start. • A mix of experience report and tips-and- tricks • This is also just about learning something new.
  • 7. A way to learn • Understand enough to make something, however messy • Make it smaller • Introduce third-party code • Start over
  • 9. The final version system http://markforster.squarespace.com/
  • 10. Final Version system • Keep a list of tasks • Mark the first item with a dot • Go down the list until you find an item you want to do before the closest dotted item above • Repeat until you reach the end of the list • Then attend to the tasks in bottom-up order • Delete completed items, and otherwise move items to the end when you stop working on them • When nothing is left dotted, start dotting at the top again
  • 11. Example Write slides for meetup Prepare TPS report Get a haircut Contemplate my mortality Eat some ice cream
  • 12. Example • Write slides for meetup Prepare TPS report • Get a haircut Contemplate my mortality • Eat some ice cream
  • 13. Example • Write slides for meetup Prepare TPS report • Get a haircut Contemplate my mortality • Eat some ice cream
  • 17. Here’s what some rubymotion code looks like
  • 19. class TaskImageController < UIImagePickerController def viewDidLoad self.sourceType = has_camera? ? UIImagePickerControllerSourceTypeCamera : UIImagePickerControllerSourceTypePhotoLibrary self.mediaTypes = [KUTTypeImage] self.delegate = self self.allowsImageEditing = false end def imagePickerControllerDidCancel(picker) presentingViewController.dismissModalViewControllerAnimated(true) end def imagePickerController(picker, didFinishPickingMediaWithInfo:info) mediaType = info[UIImagePickerControllerMediaType] TaskList.shared.add_photo_task(info[UIImagePickerControllerOriginalImage]) presentingViewController.dismissModalViewControllerAnimated(true) end def has_camera? UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceTypeCamera) end end
  • 20. class TaskList TaskListChangedNotification = 'TaskListChanged' def self.shared @instance ||= TaskList.new end def all_tasks TaskStore.shared.all_tasks end def add_text_task(text) make_change do return if text == '' TaskStore.shared.create_task do |task| task.date_moved = NSDate.date task.text = text task.dotted = false task.active = false task.photo = false end end end def add_photo_task(image) make_change do TaskStore.shared.create_task do |task| task.date_moved = NSDate.date task.dotted = false task.active = false task.photo = true task.photo_uuid = BubbleWrap.create_uuid scaled_image = ImageStore.saveImage(image, forTask:task)
  • 21. What is RubyMotion? • Ruby re-implemented on top of iOS • Ruby statically compiled • Terminal-based toolchain • Keep using your favorite editor • Amazing community (slide stolen from Laurent Sansonetti talk “RubyMotion: Ruby in your pocket” by Laurent Sansonett via http://youtu.be/gG9GTUTI9ys)
  • 22. How is it different from Ruby? • added named arguments • no eval • no define_method • no require • most gems don’t work out of the box
  • 24. Basic idea: Really understand a working RubyMotion program
  • 25. Pierre Menard, Author of the Quixote http://www.coldbacon.com/writing/borges-quixote.html
  • 26. He did not want to compose another Quixote —which is easy— but the Quixote itself. Needless to say, he never contemplated a mechanical transcription of the original; he did not propose to copy it. His admirable intention was to produce a few pages which would coincide—word for word and line for line—with those of Miguel de Cervantes. [...] The first method he conceived was relatively simple. Know Spanish well, recover the Catholic faith, fight against the Moors or the Turk, forget the history of Europe between the years 1602 and 1918, be Miguel de Cervantes. Pierre Menard studied this procedure (I know he attained a fairly accurate command of seventeenth- century Spanish) but discarded it as too easy. Rather as impossible! my reader will say. Granted, but the undertaking was impossible from the very beginning and of all the impossible ways of carrying it out, this was the least interesting. To be, in the twentieth century, a popular novelist of the seventeenth seemed to him a diminution. To be, in some way, Cervantes and reach the Quixote seemed less arduous to him—and, consequently, less interesting—than to go on being Pierre Menard and reach the Quixote through the experiences of Pierre Menard.
  • 29. Apple Developer docs http://developer.apple.com/library/IOs
  • 33. When you need to translate • Making API calls • Reading/using sample code
  • 34. RubyMotion runtime guide http://www.rubymotion.com/developer-center/guides/runtime/
  • 36. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"TimeZoneCell"; TimeZoneCell *timeZoneCell = (TimeZoneCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (timeZoneCell == nil) { timeZoneCell = [[[TimeZoneCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT); } Region *region = [displayList objectAtIndex:indexPath.section]; NSArray *regionTimeZones = region.timeZoneWrappers; [timeZoneCell setTimeZoneWrapper:[regionTimeZones objectAtIndex:indexPath.row]]; return timeZoneCell; } http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/TableView_iPhone/TableViewCells/TableViewCells.html
  • 37. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"TimeZoneCell"; TimeZoneCell *timeZoneCell = (TimeZoneCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (timeZoneCell == nil) { timeZoneCell = [[[TimeZoneCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT); } Region *region = [displayList objectAtIndex:indexPath.section]; NSArray *regionTimeZones = region.timeZoneWrappers; [timeZoneCell setTimeZoneWrapper:[regionTimeZones objectAtIndex:indexPath.row]]; return timeZoneCell; }
  • 38. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"TimeZoneCell"; TimeZoneCell *timeZoneCell = (TimeZoneCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (timeZoneCell == nil) { timeZoneCell = [[[TimeZoneCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT); } Region *region = [displayList objectAtIndex:indexPath.section]; NSArray *regionTimeZones = region.timeZoneWrappers; [timeZoneCell setTimeZoneWrapper:[regionTimeZones objectAtIndex:indexPath.row]]; return timeZoneCell; } CellIdentifier = "TimeZoneCell" def tableView(tableView, cellForRowAtIndexPath:indexPath) timeZoneCell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) if (timeZoneCell == nil) { timeZoneCell = TimeZoneCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier:CellIdentifier) timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT) } region = displayList.objectAtIndex(indexPath.section) regionTimeZones = region.timeZoneWrappers timeZoneCell.setTimeZoneWrapper(regionTimeZones.objectAtIndex(indexPath.row)) timeZoneCell end
  • 39. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"TimeZoneCell"; TimeZoneCell *timeZoneCell = (TimeZoneCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (timeZoneCell == nil) { timeZoneCell = [[[TimeZoneCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT); } Region *region = [displayList objectAtIndex:indexPath.section]; NSArray *regionTimeZones = region.timeZoneWrappers; [timeZoneCell setTimeZoneWrapper:[regionTimeZones objectAtIndex:indexPath.row]]; return timeZoneCell; } CellIdentifier = "TimeZoneCell" def tableView(tableView, cellForRowAtIndexPath:indexPath) timeZoneCell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) || begin timeZoneCell = TimeZoneCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier:CellIdentifier) timeZoneCell.frame = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT) timeZoneCell end region = displayList[indexPath.section] regionTimeZones = region.timeZoneWrappers timeZoneCell.timeZoneWrapper = regionTimeZones[indexPath.row] timeZoneCell end
  • 40. About 30% reduction in code size, without much Rubification
  • 41. This is as much Objective-C as I needed to know
  • 43. BubbleWrap A collection of (tested) helpers and wrappers used to wrap CocoaTouch code and provide more Ruby like APIs. http://bubblewrap.io/
  • 44. addGestureRecognizer(UITapGestureRecognizer.alloc.initWithTarget(self, action:"handleTap")) addGestureRecognizer(UISwipeGestureRecognizer.alloc.initWithTarget(self, action:"handleRightSwipe")) leftRecognizer = UISwipeGestureRecognizer.alloc.initWithTarget(self, action:"handleLeftSwipe") leftRecognizer.direction = UISwipeGestureRecognizerDirectionLeft addGestureRecognizer(leftRecognizer) def handleTap TaskList.shared.toggle_dotted(taskID) end def handleRightSwipe TaskList.shared.remove_task(taskID) if @active end def handleLeftSwipe TaskList.shared.pause_task(taskID) if @active end Before when_tapped { TaskList.shared.toggle_dotted(taskID) } when_swiped_right { TaskList.shared.remove_task(taskID) if @active } when_swiped_left { TaskList.shared.pause_task(taskID) if @active } After
  • 45. sugarcube a small library of extensions to the Ruby built-in classes that make it a little easier - and hopefully more “rubyesque” - to work in Cocoa. https://github.com/rubymotion/sugarcube
  • 46. Using other people’s objective-c code
  • 47. Using third-party libraries • vendoring • cocoapods
  • 48. Finding ios libraries http://www.cocoacontrols.com/
  • 49. cocoapods (go ye with caution) http://cocoapods.org/
  • 51. Find someone who knows more than you
  • 52. RubyMotion Google Group http://groups.google.com/group/rubymotion

Notes de l'éditeur

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n