SlideShare ist ein Scribd-Unternehmen logo
1 von 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

Weitere ähnliche Inhalte

Ähnlich wie 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
 

Ähnlich wie 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
 

Kürzlich hochgeladen

FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
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
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
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
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
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
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
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
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 

Kürzlich hochgeladen (20)

FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
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
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
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
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
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
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
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
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 

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

Hinweis der Redaktion

  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