diff --git a/lib/motion/project/builder.rb b/lib/motion/project/builder.rb index 72267e28..82f0baff 100644 --- a/lib/motion/project/builder.rb +++ b/lib/motion/project/builder.rb @@ -343,17 +343,20 @@ EOS end # Compile Asset Catalog bundles. - xcassets = [] - config.resources_dirs.each do |dir| - xcassets.concat(Dir.glob(File.join(dir, '*.xcassets'))) if File.exist?(dir) - end + xcassets = config.xcassets_bundles unless xcassets.empty? - xcassets.map! { |f| File.expand_path(f) } sh "\"#{config.xcode_dir}/usr/bin/actool\" --output-format human-readable-text " \ "--notices --warnings --platform #{config.deploy_platform.downcase} " \ "--minimum-deployment-target #{config.deployment_target} " \ "#{Array(config.device_family).map { |d| "--target-device #{d}" }.join(' ')} " \ "--compress-pngs --compile \"#{File.expand_path(bundle_path)}\" \"#{xcassets.join('" "')}\"" + # App icons still need to be handled as always, so we need to copy those + # into the app bundle. + if icons = config.app_icons_from_xcassets + icons.each do |image_src, image_dest_filename| + copy_resource(image_src, File.join(bundle_path, image_dest_filename)) + end + end end # Compile CoreData Model resources and SpriteKit atlas files. @@ -420,12 +423,7 @@ EOS if reserved_app_bundle_files.include?(res) App.fail "Cannot use `#{res_path}' as a resource file because it's a reserved application bundle file" end - dest_path = File.join(app_resources_dir, res) - if !File.exist?(dest_path) or File.mtime(res_path) > File.mtime(dest_path) - FileUtils.mkdir_p(File.dirname(dest_path)) - App.info 'Copy', res_path - FileUtils.cp_r(res_path, dest_path) - end + copy_resource(res_path, File.join(app_resources_dir, res)) end # Delete old resource files. @@ -435,6 +433,7 @@ EOS next if File.directory?(bundle_res) next if reserved_app_bundle_files.include?(bundle_res) next if resources_files.include?(bundle_res) + next if config.icons.include?(File.basename(bundle_res)) App.warn "File `#{bundle_res}' found in app bundle but not in resource directories, removing" FileUtils.rm_rf(bundle_res) end @@ -466,6 +465,14 @@ EOS eval `#{@nfd} "#{string}"` end + def copy_resource(res_path, dest_path) + if !File.exist?(dest_path) or File.mtime(res_path) > File.mtime(dest_path) + FileUtils.mkdir_p(File.dirname(dest_path)) + App.info 'Copy', res_path + FileUtils.cp_r(res_path, dest_path) + end + end + class << self def common_build_dir dir = File.expand_path("~/Library/RubyMotion/build") diff --git a/lib/motion/project/template/ios/config.rb b/lib/motion/project/template/ios/config.rb index c5ab5833..74221e5c 100644 --- a/lib/motion/project/template/ios/config.rb +++ b/lib/motion/project/template/ios/config.rb @@ -38,7 +38,6 @@ module Motion; module Project; @interface_orientations = [:portrait, :landscape_left, :landscape_right] @background_modes = [] @status_bar_style = :default - @icons = [] @prerendered_icon = false @manifest_assets = [] end @@ -57,6 +56,38 @@ module Motion; module Project; end end + def icons + @icons ||= app_icons_from_xcassets.map(&:last) + end + + def app_icons_from_xcassets + unless @app_icons_from_xcassets + @app_icons_from_xcassets = [] + app_icon_sets = xcassets_bundles.map { |b| Dir.glob(File.join(b, '*.appiconset')) }.flatten + if app_icon_sets.size > 1 + # TODO should we just App.fail here? + $stderr.puts '[!] More than one AppIcon set was found across all xcasset bundles. Only the first one (alphabetically) will be used.' + end + if app_icon_set = app_icon_sets.sort.first + app_icon_filename = File.basename(app_icon_set, File.extname(app_icon_set)) + # TODO need to think how to solve this on stock OS X Ruby 1.8.7, which + # doesn’t come with JSON. + require 'json' + images = JSON.parse(File.read(File.join(app_icon_set, 'Contents.json')))['images'] + images.each do |image| + if image_src = image['filename'] + image_src = File.join(app_icon_set, image_src) + if File.exist?(image_src) + image_filename = "#{app_icon_filename}#{image['size']}@#{image['scale']}.png" + @app_icons_from_xcassets << [image_src, image_filename] + end + end + end + end + end + @app_icons_from_xcassets + end + def validate # icons if !(icons.is_a?(Array) and icons.all? { |x| x.is_a?(String) }) diff --git a/lib/motion/project/template/osx/config.rb b/lib/motion/project/template/osx/config.rb index d2d1c500..d62a1b24 100644 --- a/lib/motion/project/template/osx/config.rb +++ b/lib/motion/project/template/osx/config.rb @@ -67,6 +67,10 @@ module Motion; module Project; archs end + # TODO no-op for now + def app_icons_from_xcassets + end + def locate_compiler(platform, *execs) execs.each do |exec| cc = File.join('/usr/bin', exec) diff --git a/lib/motion/project/xcode_config.rb b/lib/motion/project/xcode_config.rb index e943ca39..e6cac2bd 100644 --- a/lib/motion/project/xcode_config.rb +++ b/lib/motion/project/xcode_config.rb @@ -322,5 +322,15 @@ EOS path = File.join(xcode_dir, 'usr/bin/TextureAtlas') File.exist?(path) ? path : nil end + + def xcassets_bundles + xcassets_bundles = [] + resources_dirs.each do |dir| + if File.exist?(dir) + xcassets_bundles.concat(Dir.glob(File.join(dir, '*.xcassets'))) + end + end + xcassets_bundles + end end end; end