RubyMotion — это набор инструментов, который упрощает разработку приложений для iOS, компилируя исходный код на родной машинный язык iOS. Он делится своим наследием с MacRuby, что делает опытным Rubyists привычным вариантом для разработки приложений для iPhone / iPod / iPad.
RubyMotion обеспечивает прямой доступ к классам и библиотекам iOS, RubyGems и поддерживает смешивание соглашений о вызовах в стиле Ruby и Objective-C.
Структура приложения iOS соответствует MVC (например, Rails), а рабочий процесс командной строки RubyMotion управляется Rakefile; так же, как Rails .
Ваш стандартный рабочий процесс в RubyMotion, вероятно, будет включать в себя Bundler и RVM {На момент написания этой статьи RubyMotion требовал минимум Ruby 1,9}
Но это сходство с Ruby on Rails во многих случаях является лишь поверхностным.
В этой статье я хочу сосредоточиться на Rakefile, который используется в приложениях RubyMotion. И я надеюсь оказать некоторую помощь в поддержании вашей работы немного более организованной (и DRY), когда у вас есть несколько приложений RubyMotion в разработке.
Методы и идеи, которые я здесь представляю, являются моими собственными, не несут особой гарантии и представлены в качестве руководства Вам предлагается взять то, что представлено здесь, и расширить его или настроить в соответствии с вашими потребностями.
Если вы создадите что-то особенно интересное или уникальное, я надеюсь, что вы поделитесь этим с сообществом (в Gist или репозитории на Github ) и прокомментируете это сообщение.
Структура проекта RubyMotion
Чтобы создать новое приложение (проект), нужно просто motion create applicationName
Это строит структуру приложения RubyMotion так:
applicationName
Rakefile
resources
app
app_delegate.rb
.gitignore
spec
main_spec.rb
Если вы знакомы с разработкой для iOS (возможно, вы работали в Objective-C с XCode), appdelegate.rb
- Каталог
resources
ресурсы . -
.gitignore
Хотя вам все равно потребуетсяgit init
- Каталог
spec
RubyMotion использует Bacon (клон RSpec). И образец спецификации создается по умолчанию. Эта система сборки, которая генерирует эти файлы, является Open Source на Github в HipByte / RubyMotion . Часть этой системы, которая будет фокусироваться в этой статье, являетсяRakefile
Rakefile Rakefile
Очень похоже на Rails, большинство задач, которые вам нужны, это всего лишь команда rake
Вы можете создавать собственные задачи, редактируя их и получая список текущих задач с вызовом rake -T
Вот список команд rake
rake archive # Create an .ipa archive
rake archive:distribution # Create an .ipa archive for distribution (AppStore)
rake build # Build everything
rake build:device # Build the device version
rake build:simulator # Build the simulator version
rake clean # Clear build objects
rake config # Show project config
rake ctags # Generate ctags
rake default # Build the project, then run the simulator
rake device # Deploy on the device
rake simulator # Run the simulator
rake spec # Same as 'spec:simulator'
rake spec:device # Run the test/spec suite on the device
rake spec:simulator # Run the test/spec suite on the simulator
rake static # Create a .a static library
Rake Holds Подробности конфигурации
В отличие от Rails, где вам редко требуется изменять Rakefile
Другими словами, каждое приложение в RubyMotion будет иметь свою собственную — уникальную — версию Rakefile
На большинство библиотек и гемов, которые вы хотите запросить (из-за статической компиляции, RubyMotion не может поддерживать ‘include’), будут ссылаться в Rakefile
Конкретные значки, используемые в вашем приложении, и учетные данные Codesign должны быть добавлены в Rakefile
Кроме того, любые учетные данные для API, которые вы можете использовать, читаются из Rakefile
{Вы всегда можете проверить текущую конфигурацию с помощью config rake config
Дилемма
Я всегда не решался включить Rakefile
особенно на проектах, которые я могу предложить публично. Но поскольку это неотъемлемая часть всего процесса, его нельзя просто исключить.
Как скрыть какие-либо «проприетарные» учетные данные, предоставляя необходимые детали конфигурации, было предметом многочисленных дискуссий в сообществе RubyMotion. Одним из очевидных (и очень популярных) решений является определение «переменных среды» для этих конфиденциальных фрагментов данных.
Хотя это работает хорошо, я хочу большей гибкости и предпочитаю что-то менее тесно связанное с любым конкретным устройством (я работаю на нескольких компьютерах).
Мое решение
В моем рабочем процессе RubyMotion я решил определить Rakefile
Моя символическая ссылка Rakefile
один Rakefile, который находится в родительском каталоге. Это очень СУХОЙ подход к управлению Rakefile
Чтобы обеспечить необходимую гибкость, я изменил этот базовый Rakefile
app_properties.rb
Вот пример общего Rakefile
Это предполагает, что Rakefile
один уровень выше любого проекта RubyMotion. {Этот файл был анонимным для публикации}
#-*- coding: utf-8 -*-
$:.unshift("/Library/RubyMotion/lib")
require 'motion/project'
# custom rake tasks can go here
desc "Open latest crash log"
task :log do
app = Motion::Project::App.config
exec "less '#{Dir[File.join(ENV['HOME'], "/Library/Logs/DiagnosticReports/#{app.name}*")].last}'"
end
require './app_properties' #this is the call to a file that exists in every project
props = AppProperties.new
props.requires.each { |r| require r } if props.requires.size > 0
Motion::Project::App.setup do |app|
app.name = props.name
app.identifier = props.identifier
app.delegate_class = props.delegate
app.version = props.version.scan(/d+/).flatten.first
app.short_version = props.version.scan(/d+/).first #required to be incremented for AppStore (http://iconoclastlabs.com/cms/blog/posts/updating-a-rubymotion-app-store-submission)
app.icons = props.icons
app.device_family = props.devices
app.interface_orientations = props.orientations
app.provisioning_profile = props.provisioning
app.codesign_certificate = props.developer_certificate
if props.testflight?
require 'motion-testflight'
app.testflight.sdk = 'vendor/TestFlight'
app.testflight.api_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
app.testflight.team_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
app.testflight.distribution_lists = ['Developers', 'Testers']
end
if props.pixate?
require 'rubygems'
require 'motion-pixate'
app.pixate.user = 'USER ID'
app.pixate.key = 'XXXX-XXXX-XXXX-XXXX-XXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXX-XX'
app.pixate.framework = 'vendor/PXEngine.framework'
end
end
И пример файла app_properties.rb
class AppProperties
VERSION = '0.9'
APP_DELEGATE = 'AppDelegate' #default
COMPANY_NAME = 'com.websembly.'
def name
'App Name Here'
end
def version
VERSION
end
def requires #add libraries to listed in Rakefile as 'require'
["sugarcube"]
end
def frameworks
[]
end
def contributors
["Thom Parkin" => "https://github.com/ParkinT/"]
end
def developer_certificate
'iPhone Developer: Thom Parkin (1337THX1138)'
end
def provisioning
'./provisioning' #symlink
end
def testflight?
false
end
def pixate?
true
end
def delegate
APP_DELEGATE
end
def icons
icn = ["#{self.name}.png", "#{self.name}-72.png", "#{self.name}@2x.png"]
end
def devices
[:iphone, :ipad]
end
def orientations
[:portrait, :landscape_left, :landscape_right] #:portrait_upside_down
end
def identifier
COMPANY_NAME + APP_DELEGATE
end
end
Вы можете заметить, что профиль обеспечения также является символической ссылкой.
И так, в каждом из моих проектов Rakefile
create
app_properties.rb
Гибкость и ценность этого продолжает расти, поскольку я расширяю свое использование библиотек и дополнительных помощников в моем рабочем процессе RubyMotion. Например, я недавно начал использовать Pixate в своих проектах RubyMotion. Чтобы добавить эту возможность во все мои проекты RubyMotion, я просто обновил основной Rakefile
app_properties.rb
Как я уже говорил, это ОДИН СПОСОБ для достижения этого эффекта. Возможно, это не самый лучший способ, и я предлагаю вам улучшить его. Если да, пожалуйста, дайте мне знать.