Module: Everywhere::AssetCatalog

Defined in:
lib/everywhere/asset_catalog.rb

Overview

Compiles an app's native/ios/assets/ tree into Assets.xcassets imagesets so native code can reach them by name — Image("logo") in SwiftUI, UIImage(named: "logo") in UIKit. The catalog already ships in the frozen template and is compiled by actool, so writing imagesets into it keeps the stamp-only contract (the pbxproj is never touched).

Filenames are the whole API: [@2x|@3x][~dark].. Sub-directories organise the catalog but do NOT namespace it — asset names stay global, so assets/branding/logo.png is still Image("logo").

Constant Summary collapse

RASTER =
%w[.png .jpg .jpeg].freeze
VECTOR =
%w[.pdf .svg].freeze
EXTENSIONS =
(RASTER + VECTOR).freeze
RESERVED =

Written by the iOS builder itself (icon, launch background, tint) — an app asset of the same name would silently lose to, or clobber, those.

%w[AppIcon AccentColor LaunchBackground].freeze
VALID_NAME =
/\A[A-Za-z0-9_][A-Za-z0-9_.-]*\z/
INFO =
{ "author" => "xcode", "version" => 1 }.freeze

Class Method Summary collapse

Class Method Details

.write!(source, catalog) ⇒ Object

Copy every image under source into catalog as an imageset. Returns [names, errors]; nothing is written when errors is non-empty, so a broken assets/ tree can't half-stamp a catalog.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/everywhere/asset_catalog.rb', line 32

def write!(source, catalog)
  sets, errors = plan(source)
  return [[], errors] unless errors.empty?

  sets.each do |set|
    group = set[:dir] == "." ? catalog : File.join(catalog, set[:dir])
    dir = File.join(group, "#{set[:name]}.imageset")
    FileUtils.mkdir_p(dir)
    set[:variants].each { |v| FileUtils.cp(v[:path], File.join(dir, File.basename(v[:path]))) }
    File.write(File.join(dir, "Contents.json"), "#{JSON.pretty_generate(contents(set))}\n")
    write_group_folders(catalog, set[:dir])
  end

  [sets.map { |set| set[:name] }.sort, []]
end