Class: Everywhere::Builders::Ios

Inherits:
Base
  • Object
show all
Defined in:
lib/everywhere/builders/ios.rb

Overview

Assembles a Hotwire Native iOS app around an already-deployed (remote mode) app. No Tebako on iOS — the "build" is: copy the gem's frozen Xcode template, stamp it (xcconfig + everywhere.json + AppIcon; never the pbxproj), and hand it to xcodebuild.

Two products come out of the same stamped project: the Simulator .app (ad-hoc signed, no certs) and, with device: true, a signed .ipa via xcodebuild archive + -exportArchive — see platform/docs/build-engine.md §5.

Constant Summary collapse

SCHEME =

Fixed by the template contract: the target/product is always "App" (App.app), so build paths never depend on per-app values.

"App"
REQUIRED_SIGNING_ENV =

Device signing arrives through the environment, never everywhere.yml: the platform runner pulls the certificate and profile just-in-time and nothing lands in the app repo.

{
  "EVERY_IOS_TEAM_ID" => "the 10-character Apple Developer team id",
  "EVERY_IOS_PROVISIONING_PROFILE" => "the provisioning profile NAME (not a path or UUID)"
}.freeze
EXPORT_METHODS =
%w[app-store-connect app-store ad-hoc development release-testing enterprise].freeze
DEFAULT_EXPORT_METHOD =
"app-store-connect"
STORE_CHANNELS =

Distribution channels whose artifact has to reach App Store Connect: the upload happens here, on the build host, because only this machine has the archive and Xcode.

%w[testflight app_store].freeze
ASC_ENV =

The App Store Connect API key, under the names the platform runner already exports for notarytool, plus explicit aliases for local runs.

{
  key_path: %w[NOTARY_KEY EVERY_ASC_KEY],
  key_id: %w[NOTARY_KEY_ID EVERY_ASC_KEY_ID],
  issuer_id: %w[NOTARY_ISSUER EVERY_ASC_ISSUER_ID]
}.freeze

Constants inherited from Base

Base::STAGE_MARKER

Instance Method Summary collapse

Constructor Details

#initialize(config:, root:, target:, template_dir: nil, channel: "direct") ⇒ Ios

Returns a new instance of Ios.



54
55
56
57
# File 'lib/everywhere/builders/ios.rb', line 54

def initialize(config:, root:, target:, template_dir: nil, channel: "direct")
  super(config: config, root: root, target: target, template_dir: template_dir)
  @channel = channel.to_s
end

Instance Method Details

#build!(dist_dir:, dev: false, device: false) ⇒ Object

Build the Simulator .app and copy it into dist_dir. dev builds Debug and relaxes the remote-mode requirement (the dev URL arrives at launch via SIMCTL_CHILD_EVERYWHERE_DEV_URL, not baked into the bundle). device archives and exports a signed dist/.ipa instead. Returns the path of the built product.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/everywhere/builders/ios.rb', line 64

def build!(dist_dir:, dev: false, device: false)
  preflight!(dev: dev, device: device)
  @device = device
  template = @template_dir ? File.expand_path(@template_dir) : Paths.ios_dir!
  work = stage(template)
  stamp!(work)
  if device
    archive!(work, dist_dir)
    return export!(work, dist_dir)
  end

  configuration = dev ? "Debug" : "Release"
  xcodebuild!(work, configuration, dist_dir)
  collect(configuration, dist_dir)
end