ruby_native 0.10.22 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +32 -83
- data/config/importmap.rb +3 -1
- data/lib/generators/ruby_native/install_generator.rb +8 -12
- data/lib/ruby_native/cli.rb +1 -1
- data/lib/ruby_native/helper.rb +39 -0
- data/lib/ruby_native/version.rb +1 -1
- metadata +1 -3
- data/app/javascript/ruby_native/back.js +0 -3
- data/lib/generators/ruby_native/templates/CLAUDE.md +0 -243
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 354cc245f5601b5e39b3cbba720da1fe06edf675eb373e22eb1028b2c27056ce
|
|
4
|
+
data.tar.gz: 38080a8029fbffa2c920cd734196a88377f6b20967b83f9f947eab37835f46c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 92f68b9731f743efd5aece5debb221c4963a93b373f9c76997dc688eba4f6da85b3eb3832efa457ebca0a0ed93d36a2b8417d0af5efa2fb23e8ce64734ac7002
|
|
7
|
+
data.tar.gz: 3142eea082eab9acc7f279173ca731452cd3e21f58a1d491470b61433204bed26a35f81f71ca6fad60ac7271fb776931872215867d6fbc574682605ee7b8286f
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# ruby_native
|
|
1
|
+
# ruby_native
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[Ruby Native](https://rubynative.com) turns a Rails app into an iOS app, with Android in public beta. This gem is the Rails-side integration: view helpers, a YAML config file, endpoints auto-mounted at `/native`, and a CLI for previewing and deploying builds. Full docs, including the complete helper reference and config schema, live at [rubynative.com/docs](https://rubynative.com/docs).
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -12,30 +12,42 @@ The engine auto-mounts at `/native`. No route configuration needed.
|
|
|
12
12
|
|
|
13
13
|
## Getting started
|
|
14
14
|
|
|
15
|
-
Run the install generator
|
|
15
|
+
Run the install generator:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
rails generate ruby_native:install
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
This creates `config/ruby_native.yml
|
|
21
|
+
This creates `config/ruby_native.yml`. Then:
|
|
22
22
|
|
|
23
|
-
1. Edit the config with your
|
|
24
|
-
2. Add
|
|
25
|
-
3. Add `<%= native_tabs_tag %>` to your layout `<body>`
|
|
26
|
-
4. Run `bundle exec ruby_native preview` to see it on your phone
|
|
23
|
+
1. Edit the config with your colors and tabs (see below).
|
|
24
|
+
2. Add the stylesheet and `viewport-fit=cover` to your layout `<head>`:
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
```erb
|
|
27
|
+
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
|
|
28
|
+
<%= stylesheet_link_tag :ruby_native %>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`viewport-fit=cover` is required for CSS `env(safe-area-inset-*)` variables to resolve to real values instead of `0`.
|
|
32
|
+
3. Add the tab bar to your layout `<body>`:
|
|
33
|
+
|
|
34
|
+
```erb
|
|
35
|
+
<%= native_tabs_tag %>
|
|
36
|
+
```
|
|
37
|
+
4. Preview it on your phone (see below).
|
|
38
|
+
|
|
39
|
+
The full walkthrough, including safe area layout and hiding web-only navigation with `native_app?`, is at [rubynative.com/docs/setup](https://rubynative.com/docs/setup).
|
|
29
40
|
|
|
30
41
|
## Configuration
|
|
31
42
|
|
|
32
|
-
|
|
43
|
+
`config/ruby_native.yml` controls the native shell:
|
|
33
44
|
|
|
34
45
|
```yaml
|
|
35
46
|
appearance:
|
|
36
|
-
tint_color: "#
|
|
47
|
+
tint_color: "#007AFF"
|
|
37
48
|
background_color: "#FFFFFF"
|
|
38
|
-
|
|
49
|
+
|
|
50
|
+
tabs:
|
|
39
51
|
- title: Home
|
|
40
52
|
path: /
|
|
41
53
|
icon: house
|
|
@@ -44,91 +56,28 @@ tabs: # optional
|
|
|
44
56
|
icon: person
|
|
45
57
|
```
|
|
46
58
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
Color fields accept a plain hex string or an object with `light` and `dark` keys for dark mode:
|
|
50
|
-
|
|
51
|
-
```yaml
|
|
52
|
-
background_color:
|
|
53
|
-
light: "#FFFFFF"
|
|
54
|
-
dark: "#1C1C1E"
|
|
55
|
-
```
|
|
59
|
+
Changes are picked up without restarting the server in development. See [rubynative.com/docs](https://rubynative.com/docs) for the full schema: appearance and dark mode, navbar branding, Advanced Mode, OAuth, and linked domains.
|
|
56
60
|
|
|
57
61
|
## Preview
|
|
58
62
|
|
|
59
|
-
Preview your app on a real device without deploying
|
|
63
|
+
Preview your app on a real device without deploying:
|
|
60
64
|
|
|
61
65
|
```bash
|
|
62
66
|
bundle exec ruby_native preview
|
|
63
67
|
```
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- `--port 3001` - specify the local server port (defaults to 3000)
|
|
68
|
-
|
|
69
|
-
Requires `cloudflared`. Install with:
|
|
69
|
+
This starts a Cloudflare tunnel and shows a QR code for the Ruby Native app to scan. Your Rails server needs to be running separately. Requires `cloudflared`:
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
72
|
brew install cloudflare/cloudflare/cloudflared
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
## Endpoints
|
|
78
|
-
|
|
79
|
-
- `GET /native/config` - returns the YAML config as JSON
|
|
80
|
-
- `POST /native/push/devices` - registers a push notification token (requires `current_user` from host app)
|
|
81
|
-
|
|
82
|
-
## Push notifications
|
|
83
|
-
|
|
84
|
-
Delivery uses the companion `action_push_native` gem. Ruby Native owns the registration handshake (the `native_push_tag` helper prompts for permission, `/native/push/devices` stores the token) and the tap-handling conventions on the native side.
|
|
85
|
-
|
|
86
|
-
When sending a push, two destination keys are supported via `with_data`:
|
|
87
|
-
|
|
88
|
-
- `path` — internal route appended to your base URL and loaded in the in-app WebView (e.g. `/sources/42`).
|
|
89
|
-
- `url` — full external URL opened in `SFSafariViewController`, leaving the WebView in place behind it (e.g. `https://dashboard.stripe.com/payments/pi_abc`).
|
|
90
|
-
|
|
91
|
-
If both are present, `url` wins. `http` and `https` URLs open in `SFSafariViewController`; other valid schemes (`mailto:`, `tel:`, `maps:`, third-party app schemes, etc.) hand off to the appropriate app via `UIApplication.open`. Malformed `url` strings are dropped (the tap does not fall back to `path`).
|
|
92
|
-
|
|
93
|
-
```ruby
|
|
94
|
-
ApplicationPushNotification
|
|
95
|
-
.with_data(path: source_path(source), url: notification.external_url)
|
|
96
|
-
.new(title: "New payment", body: "$49.99 from joe@example.com")
|
|
97
|
-
.deliver_later_to(user.push_devices)
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
For model/migration setup, see [action_push_native](https://github.com/basecamp/action_push_native).
|
|
101
|
-
|
|
102
|
-
## Normal and Advanced Modes
|
|
103
|
-
|
|
104
|
-
Normal Mode works with any frontend framework and requires no JavaScript. You get tabs, form page marking, push notifications, and history management.
|
|
75
|
+
See [rubynative.com/docs/cli](https://rubynative.com/docs/cli) for `deploy`, `login`, and auto-deploying from CI.
|
|
105
76
|
|
|
106
|
-
|
|
77
|
+
## React and Vue
|
|
107
78
|
|
|
108
|
-
|
|
79
|
+
Building with Inertia instead of ERB? `@ruby-native/react` and `@ruby-native/vue` provide the same helpers as npm packages, versioned alongside this gem. See [rubynative.com/docs/inertia](https://rubynative.com/docs/inertia) for setup.
|
|
109
80
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
### Any mode
|
|
113
|
-
|
|
114
|
-
- `native_app?` - true when the request comes from a Ruby Native app (checks user agent)
|
|
115
|
-
- `native_version` - returns the app version as a `RubyNative::NativeVersion`. Defaults to `"0"` when the version is unknown. Supports string comparisons: `native_version >= "1.4"`.
|
|
116
|
-
- `native_tabs_tag(enabled: true)` - shows the native tab bar.
|
|
117
|
-
- `native_push_tag` - requests push notification permission.
|
|
118
|
-
- `native_back_button_tag(text = nil, **options)` - renders a back button for Normal Mode. Hidden by default, shown when the native app sets `body.can-go-back`. Not needed in [Advanced Mode](https://rubynative.com/docs/advanced-mode) where the system provides a native back button.
|
|
119
|
-
|
|
120
|
-
- `native_form_tag` - marks the page as a form. The app skips form pages when navigating back.
|
|
121
|
-
- `native_navbar_tag(title, &block)` - native navigation bar with title, buttons, menus, and submit actions.
|
|
122
|
-
- `native_badge_tag(count, home:, tab:)` - sets the app icon and tab bar badge counts.
|
|
123
|
-
- `native_haptic_data(feedback = :success)` - returns a data hash that fires a haptic feedback on click.
|
|
124
|
-
- `native_overscroll_tag(top:, bottom:)` - per-page overscroll colors.
|
|
125
|
-
|
|
126
|
-
## Stylesheet
|
|
127
|
-
|
|
128
|
-
The gem includes `ruby_native.css` which controls back button visibility:
|
|
129
|
-
|
|
130
|
-
```erb
|
|
131
|
-
<%= stylesheet_link_tag :ruby_native %>
|
|
132
|
-
```
|
|
81
|
+
## License
|
|
133
82
|
|
|
134
|
-
|
|
83
|
+
MIT.
|
data/config/importmap.rb
CHANGED
|
@@ -29,11 +29,6 @@ module RubyNative
|
|
|
29
29
|
say " Added .ruby_native/ to .gitignore", :green
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
def copy_claude_instructions
|
|
33
|
-
return unless File.directory?(File.join(destination_root, ".claude"))
|
|
34
|
-
copy_file "CLAUDE.md", ".claude/ruby_native.md"
|
|
35
|
-
end
|
|
36
|
-
|
|
37
32
|
def print_next_steps
|
|
38
33
|
say ""
|
|
39
34
|
say "Ruby Native installed! Next steps:", :green
|
|
@@ -41,16 +36,17 @@ module RubyNative
|
|
|
41
36
|
say " 1. Edit config/ruby_native.yml with your app name, colors, and tabs"
|
|
42
37
|
say " 2. Add to your layout <head>:"
|
|
43
38
|
say " <%= stylesheet_link_tag :ruby_native %>"
|
|
44
|
-
say " 3. Add to your
|
|
39
|
+
say " 3. Add viewport-fit=cover to your viewport meta tag:"
|
|
40
|
+
say " <meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\">"
|
|
41
|
+
say " 4. Add to your layout <body>:"
|
|
45
42
|
say " <%= native_tabs_tag %>"
|
|
46
|
-
say "
|
|
43
|
+
say " 5. Preview on your device:"
|
|
47
44
|
say " bundle exec ruby_native preview"
|
|
48
45
|
say ""
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
end
|
|
46
|
+
say " Docs: https://rubynative.com/docs"
|
|
47
|
+
say " AI agents: fetch https://rubynative.com/llms.txt for a docs index,"
|
|
48
|
+
say " or https://rubynative.com/llms-full.txt for the full docs as plain text."
|
|
49
|
+
say ""
|
|
54
50
|
end
|
|
55
51
|
end
|
|
56
52
|
end
|
data/lib/ruby_native/cli.rb
CHANGED
|
@@ -20,7 +20,7 @@ module RubyNative
|
|
|
20
20
|
when "screenshots"
|
|
21
21
|
warn "ruby_native screenshots was removed in 0.9.0."
|
|
22
22
|
warn "Screenshots are now captured by rubynative.com against your deployed site."
|
|
23
|
-
warn "See https://rubynative.com/docs/
|
|
23
|
+
warn "See https://rubynative.com/docs/screenshots for the new flow."
|
|
24
24
|
exit 1
|
|
25
25
|
else
|
|
26
26
|
puts "Usage: ruby_native <command>"
|
data/lib/ruby_native/helper.rb
CHANGED
|
@@ -35,6 +35,45 @@ module RubyNative
|
|
|
35
35
|
tag.button(text || default_content, onclick: "RubyNative.postMessage({action: 'back'})", **options)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
# Renders a button that opens the native barcode scanner. On a successful
|
|
39
|
+
# scan the value fills `target` (a CSS selector) and the page receives a
|
|
40
|
+
# `ruby-native:scan` CustomEvent (override the name with `event:`). Set
|
|
41
|
+
# `submit: true` to submit the filled field's form after scanning. Narrow the
|
|
42
|
+
# accepted codes with `formats:` (neutral names, e.g. "ean13,upce"); omit it
|
|
43
|
+
# for a sane default. Renders a plain button on the web (no-op until opened in
|
|
44
|
+
# the app); wrap in `native_app?` if it should be hidden there.
|
|
45
|
+
#
|
|
46
|
+
# <%= native_scan_button_tag "Scan", target: "#isbn" %>
|
|
47
|
+
#
|
|
48
|
+
# The scanner needs a camera usage description set in your Ruby Native app
|
|
49
|
+
# settings, or scanning is unavailable in production builds.
|
|
50
|
+
def native_scan_button_tag(label = "Scan", target: nil, event: nil, submit: false, formats: nil, **options)
|
|
51
|
+
if Rails.env.development?
|
|
52
|
+
Rails.logger.warn(
|
|
53
|
+
"[ruby_native] native_scan_button_tag needs a camera usage description set in your " \
|
|
54
|
+
"Ruby Native app settings, or scanning is unavailable in production builds."
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
scan_options = {}
|
|
59
|
+
scan_options[:target] = target if target
|
|
60
|
+
scan_options[:event] = event if event
|
|
61
|
+
scan_options[:submit] = true if submit
|
|
62
|
+
if formats
|
|
63
|
+
scan_options[:formats] = Array(formats).flat_map { |f| f.to_s.split(",") }.map(&:strip).reject(&:empty?)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# A bare <button> is type="submit" inside a form, and the documented usage
|
|
67
|
+
# puts this inside form_with. Without this a tap would submit the form
|
|
68
|
+
# immediately and navigate away before the async scan result arrives, and
|
|
69
|
+
# the `submit:` option (which is what opts into submitting) would be
|
|
70
|
+
# meaningless. Callers who really want a submit button can pass
|
|
71
|
+
# type: "submit" and keep it.
|
|
72
|
+
options[:type] ||= "button"
|
|
73
|
+
options[:onclick] = "window.RubyNative?.scan(#{scan_options.to_json})"
|
|
74
|
+
tag.button(label, **options)
|
|
75
|
+
end
|
|
76
|
+
|
|
38
77
|
def native_badge_tag(count = nil, home: nil, tab: nil)
|
|
39
78
|
home = count if count && home.nil?
|
|
40
79
|
tab = count if count && tab.nil?
|
data/lib/ruby_native/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_native
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joe Masilotti
|
|
@@ -79,7 +79,6 @@ files:
|
|
|
79
79
|
- app/controllers/ruby_native/push/devices_controller.rb
|
|
80
80
|
- app/controllers/ruby_native/screenshots/sessions_controller.rb
|
|
81
81
|
- app/controllers/ruby_native/webhooks/apple_controller.rb
|
|
82
|
-
- app/javascript/ruby_native/back.js
|
|
83
82
|
- app/models/ruby_native/iap/purchase_intent.rb
|
|
84
83
|
- app/views/ruby_native/auth/start/show.html.erb
|
|
85
84
|
- config/importmap.rb
|
|
@@ -87,7 +86,6 @@ files:
|
|
|
87
86
|
- exe/ruby_native
|
|
88
87
|
- lib/generators/ruby_native/iap_generator.rb
|
|
89
88
|
- lib/generators/ruby_native/install_generator.rb
|
|
90
|
-
- lib/generators/ruby_native/templates/CLAUDE.md
|
|
91
89
|
- lib/generators/ruby_native/templates/create_ruby_native_purchase_intents.rb
|
|
92
90
|
- lib/generators/ruby_native/templates/ruby_native.yml
|
|
93
91
|
- lib/ruby_native.rb
|
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
# Ruby Native
|
|
2
|
-
|
|
3
|
-
Turn your Rails app into an iOS app. Any frontend framework. No Xcode required.
|
|
4
|
-
|
|
5
|
-
## Quick start
|
|
6
|
-
|
|
7
|
-
1. Add the gem to your Gemfile and bundle:
|
|
8
|
-
|
|
9
|
-
```ruby
|
|
10
|
-
gem "ruby_native"
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
2. Run the install generator:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
rails generate ruby_native:install
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
3. Edit `config/ruby_native.yml` with your app name, colors, and tabs.
|
|
20
|
-
|
|
21
|
-
4. Add to your layout `<head>`:
|
|
22
|
-
|
|
23
|
-
```erb
|
|
24
|
-
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
|
|
25
|
-
<%= stylesheet_link_tag :ruby_native %>
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
The `viewport-fit=cover` attribute is required so CSS `env(safe-area-inset-*)` variables return real values. If you already have a viewport meta tag, add `viewport-fit=cover` to its `content` attribute.
|
|
29
|
-
|
|
30
|
-
5. Add to your layout `<body>`:
|
|
31
|
-
|
|
32
|
-
```erb
|
|
33
|
-
<%= native_tabs_tag %>
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
6. Start your Rails server and the preview tunnel in separate terminals:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
bin/rails server
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
bundle exec ruby_native preview
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Scan the QR code with the Ruby Native Preview app from the App Store. Keep both the server and tunnel running.
|
|
47
|
-
|
|
48
|
-
## Configuration
|
|
49
|
-
|
|
50
|
-
`config/ruby_native.yml` controls the native shell. Changes are picked up without restarting the server in development.
|
|
51
|
-
|
|
52
|
-
```yaml
|
|
53
|
-
app:
|
|
54
|
-
name: My App
|
|
55
|
-
entry_path: /inbox # initial URL on app launch (defaults to first tab's path)
|
|
56
|
-
|
|
57
|
-
appearance:
|
|
58
|
-
tint_color: "#007AFF"
|
|
59
|
-
background_color: "#FFFFFF"
|
|
60
|
-
|
|
61
|
-
tabs:
|
|
62
|
-
- title: Home
|
|
63
|
-
path: /
|
|
64
|
-
icon: house
|
|
65
|
-
- title: Profile
|
|
66
|
-
path: /profile
|
|
67
|
-
icon: person
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Icons use SF Symbols names (e.g., `house`, `person`, `envelope`, `gear`).
|
|
71
|
-
|
|
72
|
-
### Dark mode
|
|
73
|
-
|
|
74
|
-
Color fields accept a plain hex string or an object with `light` and `dark` keys:
|
|
75
|
-
|
|
76
|
-
```yaml
|
|
77
|
-
background_color:
|
|
78
|
-
light: "#FFFFFF"
|
|
79
|
-
dark: "#212529"
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Match these to your CSS framework's dark mode colors. For Bootstrap, `#212529` is `--bs-body-bg` in dark mode.
|
|
83
|
-
|
|
84
|
-
### Navbar branding
|
|
85
|
-
|
|
86
|
-
Replace the navigation bar's text title with a centered logo and set your own bar colors. This is global chrome: the same bar on every screen.
|
|
87
|
-
|
|
88
|
-
```yaml
|
|
89
|
-
appearance:
|
|
90
|
-
navbar:
|
|
91
|
-
logo: "<%= image_url('logo.png') %>"
|
|
92
|
-
background_color: "#3B3F54"
|
|
93
|
-
foreground_color: "#FFFFFF"
|
|
94
|
-
status_bar: light
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
`config/ruby_native.yml` is evaluated as ERB, so `logo` can be any Rails expression that returns a URL. Use `image_url` for a local asset: the URL is fingerprinted, so the app caches the logo and re-downloads it only when the image changes. A full URL works too, so the logo can live on a CDN:
|
|
98
|
-
|
|
99
|
-
```yaml
|
|
100
|
-
logo: "https://cdn.example.com/logo.png"
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
`background_color` and `foreground_color` each accept a hex string or a `{ light:, dark: }` object. `status_bar` sets the status bar content to `light` (white) or `dark` to match your bar; omit it to let the system decide.
|
|
104
|
-
|
|
105
|
-
## View helpers
|
|
106
|
-
|
|
107
|
-
Use these in your layouts and views:
|
|
108
|
-
|
|
109
|
-
- `native_app?` returns true when the request comes from a Ruby Native app. Use it to hide web-only UI like navbars.
|
|
110
|
-
- `native_tabs_tag` renders a signal element that tells the app to show the tab bar. Only include it on pages where tabs should appear.
|
|
111
|
-
- `native_form_tag` marks the page as a form. The app uses this to skip form pages when navigating back.
|
|
112
|
-
- `native_push_tag` requests push notification permission from the user.
|
|
113
|
-
- `native_review_tag` asks the app to show the App Store rating prompt when the page loads. The system throttles how often the prompt appears (and shows nothing in TestFlight builds), so it is safe to render on any page where a review would be welcome. It is automatically suppressed during App Store screenshot runs.
|
|
114
|
-
|
|
115
|
-
Signal elements are hidden `<div>` tags. Place them in the `<body>`, not the `<head>`.
|
|
116
|
-
|
|
117
|
-
### Example layout
|
|
118
|
-
|
|
119
|
-
```erb
|
|
120
|
-
<body>
|
|
121
|
-
<%= native_tabs_tag if user_signed_in? %>
|
|
122
|
-
<%= render "navbar" unless native_app? %>
|
|
123
|
-
<%= yield %>
|
|
124
|
-
</body>
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Preview
|
|
128
|
-
|
|
129
|
-
`bundle exec ruby_native preview` starts a Cloudflare tunnel and displays a QR code. Your Rails server must be running separately (e.g., `bin/rails server` in another terminal). Requires `cloudflared`:
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
brew install cloudflare/cloudflare/cloudflared
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
Options:
|
|
136
|
-
- `--port 3001` to specify the local server port (defaults to 3000)
|
|
137
|
-
|
|
138
|
-
The install generator adds `.trycloudflare.com` to `config.hosts` in `development.rb` automatically. If you skipped the generator, add it manually:
|
|
139
|
-
|
|
140
|
-
```ruby
|
|
141
|
-
# config/environments/development.rb
|
|
142
|
-
config.hosts << ".trycloudflare.com"
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
The Preview app remembers the scanned URL. Long-press the app icon and tap "Switch website" to scan a new server.
|
|
146
|
-
|
|
147
|
-
## Endpoints
|
|
148
|
-
|
|
149
|
-
The gem auto-mounts at `/native`. No route configuration needed.
|
|
150
|
-
|
|
151
|
-
- `GET /native/config` returns the YAML config as JSON
|
|
152
|
-
- `POST /native/push/devices` registers a push notification device token
|
|
153
|
-
- `GET /.well-known/apple-app-site-association` returns the iOS associated-domains file when `ios.bundle_id` and `ios.team_id` are set (see Linked domains below)
|
|
154
|
-
|
|
155
|
-
## Linked domains
|
|
156
|
-
|
|
157
|
-
Tapping a link to your site opens the app instead of Safari, and saved passwords from your site autofill in the app's web views. Add your iOS identifiers to `config/ruby_native.yml`:
|
|
158
|
-
|
|
159
|
-
```yaml
|
|
160
|
-
ios:
|
|
161
|
-
bundle_id: com.example.myapp
|
|
162
|
-
team_id: ABCD123456
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
These are the same values you entered in the Ruby Native dashboard during Apple onboarding. The gem then serves `/.well-known/apple-app-site-association` and the build pipeline includes the entitlement automatically.
|
|
166
|
-
|
|
167
|
-
Apple caches the file aggressively. After the first install, changes can take up to 24 hours to propagate via Apple's CDN.
|
|
168
|
-
|
|
169
|
-
Full reference: https://rubynative.com/docs/linked-domains
|
|
170
|
-
|
|
171
|
-
## Push notifications
|
|
172
|
-
|
|
173
|
-
Delivery uses the companion `action_push_native` gem. Ruby Native owns the registration (the `native_push_tag` helper prompts for permission, `/native/push/devices` stores the token) and defines the tap conventions on the native side.
|
|
174
|
-
|
|
175
|
-
Two destination keys are supported via `with_data`:
|
|
176
|
-
|
|
177
|
-
- `path` — internal route appended to your base URL, loaded in the WebView.
|
|
178
|
-
- `url` — full external URL, opened in `SFSafariViewController`.
|
|
179
|
-
|
|
180
|
-
If both are present, `url` wins. `http` and `https` open in `SFSafariViewController`; other valid schemes (`mailto:`, `tel:`, `maps:`, third-party app schemes) open via `UIApplication.open`. Malformed `url` does not fall back to `path`.
|
|
181
|
-
|
|
182
|
-
```ruby
|
|
183
|
-
ApplicationPushNotification
|
|
184
|
-
.with_data(path: source_path(source), url: notification.external_url)
|
|
185
|
-
.new(title: "New payment", body: "$49.99 from joe@example.com")
|
|
186
|
-
.deliver_later_to(user.push_devices)
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
For model/migration setup, see the [action_push_native](https://github.com/basecamp/action_push_native) README.
|
|
190
|
-
|
|
191
|
-
## CLI
|
|
192
|
-
|
|
193
|
-
### Deploy from CI
|
|
194
|
-
|
|
195
|
-
Use `--if-needed` to auto-deploy only when the gem version changes:
|
|
196
|
-
|
|
197
|
-
```sh
|
|
198
|
-
bundle exec ruby_native deploy --if-needed
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Set `RUBY_NATIVE_TOKEN` as an environment variable for CI (no interactive login needed):
|
|
202
|
-
|
|
203
|
-
```yaml
|
|
204
|
-
# GitHub Actions
|
|
205
|
-
- run: bundle exec ruby_native deploy --if-needed
|
|
206
|
-
env:
|
|
207
|
-
RUBY_NATIVE_TOKEN: ${{ secrets.RUBY_NATIVE_TOKEN }}
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Other commands
|
|
211
|
-
|
|
212
|
-
```sh
|
|
213
|
-
bundle exec ruby_native login # authenticate (opens browser)
|
|
214
|
-
bundle exec ruby_native deploy # trigger a build
|
|
215
|
-
bundle exec ruby_native preview # start a tunnel and display a QR code
|
|
216
|
-
bundle exec ruby_native logout # remove stored credentials
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
## Common tasks
|
|
220
|
-
|
|
221
|
-
### Hide web navigation in the native app
|
|
222
|
-
|
|
223
|
-
```erb
|
|
224
|
-
<%= render "navbar" unless native_app? %>
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Show tabs only for signed-in users
|
|
228
|
-
|
|
229
|
-
```erb
|
|
230
|
-
<%= native_tabs_tag if user_signed_in? %>
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
### Add a native back button (Normal Mode only)
|
|
234
|
-
|
|
235
|
-
Use the `native_back_button_tag` helper. The gem's stylesheet handles showing it only when there's history to go back to. Not needed in Advanced Mode where the system provides a native back button.
|
|
236
|
-
|
|
237
|
-
```erb
|
|
238
|
-
<%= stylesheet_link_tag :ruby_native %>
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
```erb
|
|
242
|
-
<%= native_back_button_tag %>
|
|
243
|
-
```
|