Last Updated: February 25, 2016
·
1.992K
· supremegravity

Using MapBox with RubyMotion and CocoaPods

If you've tried the one line pod MapBox you know that your app won't compile. Here's how to fix this.


The problem and the fix

Using motion-cocoapods and cocoapods you'd expect that pod 'MapBox' would work. If you add these two lines after your app.pods do ... block, you're good to go:

app.libs.delete_if { |lib| lib =~ /Proj4/ }
app.vendor_project('vendor/Pods/MapBox/Proj4', :static, products: ['libProj4.a'])

You might need to remove the vendor and build directories before it compiles. Especially if you already tried rake and had it blow up.

(There's a complete sample Rakefile and Gemfile at the end of this page)

Longer version: Project setup

  1. To try this out in a new project, run motion create --template=ios someappname
  2. Make sure you have a Gemfile referencing cocoapods and motion-cocoapods
  3. Run bundle install at the command line
  4. Make sure your Rakefile has at least everything in the sample rakefile at the end of this page

Making a map

To test it out you need to make a new UIViewController (which displays a map):

class MapViewController < UIViewController
    def viewDidLoad
        super

        tiles = RMMapBoxSource.alloc.initWithMapID "examples.map-z2effxa8"
        map = RMMapView.alloc.initWithFrame(UIScreen.mainScreen.bounds,andTilesource:tiles)
        map.zoom = 14
        map.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth
        map.delegate=self
        self.view.addSubview(map)

        center_co = CLLocationCoordinate2D.new(40.7143528,-74.00597309999999)
        map.setCenterCoordinate(center_co,animated:true)

    end
end

And change your app_delegate.rb file to display the controller:

class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)

    mvc = MapViewController.alloc.init

    @window.rootViewController = mvc
    @window.makeKeyAndVisible
    true
  end
end

Run rake and you're done!

Picture

Bonus user location tracking in one line

Add this to your controller

map.userTrackingMode = 1

And get a location tracker on your map:

Picture


Notes

  • Sometimes map.setCenterCoordinate(CLLocationCoordinate2D.new(40.7143528,-74.00597309999999),animated:true) crashes the REPL, but always works fine in .rb files.
  • In app_delegate.rb, you can replace @window with $window, but window will not work.
  • You don't need map.delegate=self in your controller to simply show a map, but you'll need to set this to work with markers and other map objects.
  • Are the classes from the pod you added not resolving? Removing the vendor and build directories and re-running rake usually fixes this.

Sample Rakefile

$:.unshift("/Library/RubyMotion/lib")
require 'motion/project/template/ios'
Bundler.require

Motion::Project::App.setup do |app|

     app.pods do
         pod 'MapBox'
     end
     app.libs.delete_if { |lib| lib =~ /Proj4/ }
     app.vendor_project('vendor/Pods/MapBox/Proj4', :static, products: ['libProj4.a'])


    #Optional--will come in handy if you do a lot of mapping/geolocation.
    app.frameworks += ["QuartzCore","CoreLocation","CoreMedia","MapKit"]
     app.pods do
         pod 'NSData+Base64'
     end
end

Sample Gemfile

source 'https://rubygems.org'
gem 'cocoapods'
gem 'motion-cocoapods'

Versions

  • motion (2.0)
  • ruby (2.0.0)
  • gem: cocoapods (0.20.2)
  • gem: cocoapods-core (0.20.2)
  • gem: motion-cocoapods (1.3.2)
  • pod: MapBox (1.0.2)