MD5/SHA1 gem for RubyMotion

I’ve released gem for making MD5/SHA1 hashes in RubyMotion. It’s handled by small ObjC code in vendor directory. You can get this gem from my github.

Add gem ‘rm-digest’  into your Gemfile , run bundle install  and you can generate MD5/SHA1 in your application.

digestSHA1String = RmDigest::SHA1.hexdigest('some string')

digestMD5String = RmDigest::MD5.hexdigest('some string')

 

Dismissing popup view tapping outside

class MyView < UIVIewController

  ...

  # set gesture to close
  def viewDidAppear(animated)
    recognizer = UITapGestureRecognizer.alloc.initWithTarget(self, action: 'handleTapBehind:')

    recognizer.setNumberOfTapsRequired(1)
    recognizer.cancelsTouchesInView = false
    self.view.window.addGestureRecognizer(recognizer)
  end

  # handle tap  
  def handleTapBehind(sender)
    if sender.state == UIGestureRecognizerStateEnded
      location = sender.locationInView(nil)
      unless self.view.pointInside(self.view.convertPoint(location, fromView: self.view.window), withEvent: nil)
        self.view.window.removeGestureRecognizer(sender)
        self.dismissViewControllerAnimated(true, completion: lambda{})
      end
    end
  end

end

 

PSTCollectionView in rubymotion

I need use UICollectionView, but target my app for iOS < 6.0. So I’ve found PSTCollectionView library and using it with my rubymotion project. You can find whole source code in my github repo.

You need to download and link PSTCollectionView directory into vendor/PSTCollectionView .

Then update yourRakefile :

app.vendor_project('vendor/PSTCollectionView', :static)
app.frameworks += %w(QuartzCore UIKit)
app.deployment_target = "5.0"
app.device_family = [:ipad]

create app/controllers  and add two files – cell.rb  and view_controller.rb

cell.rb

class Cell < PSTCollectionViewCell #PSUICollectionViewCell

  attr_accessor :label

  def initWithFrame(frame)
    if super
      @label = UILabel.alloc.initWithFrame(CGRectMake(0.0, 0.0, frame.size.width, frame.size.height))

      @label.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth
      @label.textAlignment = UITextAlignmentCenter
      @label.font = UIFont.boldSystemFontOfSize(50.0)
      @label.backgroundColor = UIColor.underPageBackgroundColor
      @label.textColor = UIColor.whiteColor
      self.contentView.addSubview(@label)
    end
    self
  end

end

and view_controller.rb

class ViewController < PSTCollectionViewController #PSUICollectionViewController

  def viewDidLoad
    super
    pinchRecognizer = UIPinchGestureRecognizer.alloc.initWithTarget(self, action:'handlePinchGesture')
    self.collectionView.addGestureRecognizer(pinchRecognizer)
    self.collectionView.registerClass(Cell, forCellWithReuseIdentifier: "MY_CELL")
  end

  def collectionView(view, numberOfItemsInSection: section)
    63
  end

  def collectionView(collectionView, cellForItemAtIndexPath: indexPath)
    cell = collectionView.dequeueReusableCellWithReuseIdentifier("MY_CELL", forIndexPath:indexPath)
    cell.label.text = 'test'
    cell
  end

  def collectionView(collectionView, layout: collectionViewLayout, sizeForItemAtIndexPath:indexPath)
    CGSizeMake(120, 120)
  end

  def collectionView(collectionView, layout: collectionViewLayout, minimumInteritemSpacingForSectionAtIndex: section)
    30
  end

  def collectionView(collectionView, layout:collectionViewLayout, minimumLineSpacingForSectionAtIndex: section)
    30
  end

end

Finally, change app_delegate.rb

class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    @window = UIWindow.alloc.initWithFrame UIScreen.mainScreen.bounds
    view_controller = ViewController.alloc.initWithCollectionViewLayout(PSTCollectionViewFlowLayout.new)
    @window.rootViewController = view_controller
    @window.makeKeyAndVisible
    true
  end
end

runrake  and voila! :)

Screen Shot 2013-02-20 at 21.56.21

PSPDFKit gem for rubymotion

I’ve just released simple gem to include PSPDFKit into rubymotion project – see https://rubygems.org/gems/pspdfkit.

Installation is pretty straightforward

add to your Rakefile :

require 'rubygems'
require 'bundler'
Bundler.require

Create Gemfile file and add:

source :rubygems

gem 'pspdfkit'

and execute bundle install .

Then you need to copy/link framework and bundle files:

mkdir vendor
cd vendor
ln -s ../../pdf/Products/PSPDFKit.embeddedframework/PSPDFKit.framework ./
cd ../resources
ln -s ../../pdf/Products/PSPDFKit.embeddedframework/Resources/PSPDFKit.bundle ./

That’s it. Run rake and test your installation.

PSPDFKit in rubymotion

Update

If you’re using Bundler, you can simply add gem ‘pspdfkit’ to your Gemfile. See more on https://github.com/tmeinlschmidt/rm-pspdfkit


As I’ve started using this famous framework, I’d like to use it in my rubymotion application. So, there’s my setup to include this fmw in rubymotion project

  • extract PSPDFKit anywhere
  • create directory vendor  in your RM project
  • create symbolic link from your unzipped PSPDFKit to vendor/PSPDFKit.framework
cd vendor
ln -s ../../pdf/Products/PSPDFKit.embeddedframework/PSPDFKit.framework ./
cd ../resources
ln -s ../../pdf/Products/PSPDFKit.embeddedframework/Resources/PSPDFKit.bundle ./

and modify Rakefile accordingly

app.vendor_project('vendor/PSPDFKit.framework', :static, products: ['PSPDFKit'], headers_dir: 'Headers')

app.libs << '/usr/lib/libz.1.1.3.dylib'

app.frameworks += %w(MessageUI AssetsLibrary MediaPlayer PSPDFKit)

try rake , it should link and start simulator.

Next step

Add some PDF file into your app resources  folder.

And then you can try to modify app/app_delegate.rb  with simple example:

class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)

    documentURL = NSBundle.mainBundle.resourceURL.URLByAppendingPathComponent "DevelopersGuide.pdf"
    @document = PSPDFDocument.PDFDocumentWithURL documentURL

    pdfController = PSPDFViewController.alloc.initWithDocument @document
    navController = UINavigationController.alloc.initWithRootViewController pdfController

    @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
    @window.makeKeyAndVisible

    @window.rootViewController = navController
  end
end

Calculate prime numbers

Tried simple Sieve of Eratosthenes in Ruby …

class MyPrime

  attr_reader :primes # there we can read then

  # compute prime numbers up to limit, default is 20
  def initialize(limit = 20)
    @primes = []
    limit = limit.to_i 
    return if limit.to_i < 2
    arr = Hash[*((2..limit).to_a*2).sort] # we can use .zip too
    (2..Math.sqrt(limit)).each do |i|
      next unless arr[i] # already removed
      (i*i..limit).step(i).each{|k| arr.delete(k)}
    end
    @primes = arr.keys.sort # return just keys
  end
end

we can add some tests

require 'test/unit'
require 'my_prime'

class TestMyPrime < Test::Unit::TestCase

  def test_20_primes
    primes = MyPrime.new(20)
    assert_equal [2, 3, 5, 7, 11, 13, 17, 19], primes.primes
  end

  def test_wo_param
    primes = MyPrime.new
    assert_equal [2, 3, 5, 7, 11, 13, 17, 19], primes.primes
  end

  def test_less_than_2
    primes = MyPrime.new(1)
    assert_equal [], primes.primes 
  end

  def test_limit_eq_2
    primes = MyPrime.new(2)
    assert_equal [2], primes.primes
  end

  def test_limit_is_string
    primes = MyPrime.new('20')
    assert_equal [2, 3, 5, 7, 11, 13, 17, 19], primes.primes
  end

  def test_limit_is_float
    primes = MyPrime.new(20.50)
    assert_equal [2, 3, 5, 7, 11, 13, 17, 19], primes.primes
  end

end

fetch all youtube links from any page

We made a list of great youtube videos on facebook comments and wanted to fetch these as a list, so I’ve been thinking how to achieve it. And there’s some javascript code you can paste into your console (javascript consone in a browser), it’ll fetch and display all the links for youtube. Easily change regexp to match url your want.

var seznam = ''; Array.prototype.slice.call(document.getElementsByTagName('a')).forEach(function(i){ if (i.href.match(/^http:\/\/www.youtube.com/) != null) {seznam+=i+"\n";}});document.getElementsByTagName('body')[0].innerHTML="<pre>"+seznam+"</pre>";