@maccesar/titools 5.1.0 → 5.2.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.
- package/README.md +44 -12
- package/agents/ti-pro.md +4 -0
- package/commands/ti-audit.md +4 -0
- package/lib/config.js +2 -0
- package/package.json +1 -1
- package/skills/purgetss/SKILL.md +4 -4
- package/skills/purgetss/references/EXAMPLES.md +3 -3
- package/skills/purgetss/references/adopting-purgetss.md +2 -2
- package/skills/purgetss/references/animation-advanced.md +2 -2
- package/skills/purgetss/references/arbitrary-values.md +8 -5
- package/skills/purgetss/references/class-categories.md +5 -5
- package/skills/purgetss/references/class-index-properties.md +6 -6
- package/skills/purgetss/references/class-index.md +2 -2
- package/skills/purgetss/references/cli-commands.md +2 -2
- package/skills/purgetss/references/dynamic-component-creation.md +2 -2
- package/skills/purgetss/references/grid-layout.md +1 -1
- package/skills/purgetss/references/migration-guide.md +34 -4
- package/skills/purgetss/references/multi-density-images.md +6 -6
- package/skills/purgetss/references/platform-modifiers.md +21 -0
- package/skills/purgetss/references/ui-ux-design.md +1 -1
- package/skills/purgetss/references/version-history.md +9 -4
- package/skills/ti-admob-unified/SKILL.md +44 -0
- package/skills/ti-admob-unified/agents/openai.yaml +4 -0
- package/skills/ti-admob-unified/assets/example/app.js +1003 -0
- package/skills/ti-admob-unified/assets/example/lib/ads.js +618 -0
- package/skills/ti-admob-unified/assets/example/library-usage.js +104 -0
- package/skills/ti-admob-unified/references/api-reference.md +592 -0
- package/skills/ti-admob-unified/references/banners.md +435 -0
- package/skills/ti-admob-unified/references/contributing.md +228 -0
- package/skills/ti-admob-unified/references/dependencies.md +85 -0
- package/skills/ti-admob-unified/references/fullscreen.md +223 -0
- package/skills/ti-admob-unified/references/game-monetization.md +17 -0
- package/skills/ti-admob-unified/references/getting-started.md +275 -0
- package/skills/ti-admob-unified/references/index.md +30 -0
- package/skills/ti-admob-unified/references/integration.md +85 -0
- package/skills/ti-admob-unified/references/library.md +189 -0
- package/skills/ti-admob-unified/references/mediation.md +132 -0
- package/skills/ti-admob-unified/references/migration.md +255 -0
- package/skills/ti-admob-unified/references/module-changelog.md +54 -0
- package/skills/ti-admob-unified/references/module-license.txt +21 -0
- package/skills/ti-admob-unified/references/privacy.md +254 -0
- package/skills/ti-admob-unified/references/roadmap.md +146 -0
- package/skills/ti-admob-unified/references/source-notes.md +33 -0
- package/skills/ti-admob-unified/references/source-snapshot.json +440 -0
- package/skills/ti-admob-unified/references/third-party-notices.md +22 -0
- package/skills/ti-game/SKILL.md +10 -1
- package/skills/ti-game/references/api.md +10 -2
- package/skills/ti-game/references/debugging-performance.md +6 -0
- package/skills/ti-game/references/examples.md +11 -1
- package/skills/ti-game/references/patterns.md +24 -2
- package/skills/ti-game/references/physics.md +502 -0
- package/skills/ti-game/references/project-setup.md +23 -1
- package/skills/ti-game/references/recipes-action.md +46 -14
- package/skills/ti-game/references/recipes-adventure-effects.md +12 -1
- package/skills/ti-game/references/roadmap.md +2 -2
- package/skills/ti-game/references/tilemaps.md +2 -1
- package/skills/ti-game-assets/SKILL.md +53 -0
- package/skills/ti-game-assets/agents/openai.yaml +4 -0
- package/skills/ti-game-assets/references/alpha.md +26 -0
- package/skills/ti-game-assets/references/art-direction.md +37 -0
- package/skills/ti-game-assets/references/integration.md +49 -0
- package/skills/ti-game-assets/references/manifest.example.json +429 -0
- package/skills/ti-game-assets/references/manifest.md +39 -0
- package/skills/ti-game-assets/references/offline-audio.md +33 -0
- package/skills/ti-game-assets/references/prompts.md +33 -0
- package/skills/ti-game-assets/references/repeating-textures.md +17 -0
- package/skills/ti-game-assets/references/responsible-ads.md +31 -0
- package/skills/ti-game-assets/references/sound-assets.md +42 -0
- package/skills/ti-game-assets/references/vector-sources.md +21 -0
- package/skills/ti-game-assets/scripts/alpha_tools.py +160 -0
- package/skills/ti-game-assets/scripts/requirements.txt +1 -0
- package/skills/ti-game-assets/scripts/validate_manifest.py +267 -0
- package/skills/ti-synthengine/SKILL.md +37 -13
- package/skills/ti-synthengine/references/api.md +397 -31
- package/skills/ti-synthengine/references/audio-engine.md +235 -14
- package/skills/ti-synthengine/references/examples.md +396 -17
- package/skills/ti-synthengine/references/guide.md +331 -12
- package/skills/ti-synthengine/references/recipes.md +212 -22
- package/skills/ti-synthengine/references/recommendations.md +53 -16
- package/skills/ti-synthengine/references/sound-design.md +359 -15
- package/skills/ti-synthengine/references/source-notes.md +121 -0
- package/skills/ti-synthengine/references/source-snapshot.json +105 -0
- package/skills/ti-synthengine/references/stats-performance.json +2992 -0
- package/skills/ti-synthengine/references/stats-performance.md +38 -0
- package/skills/ti-synthengine/references/troubleshooting.md +61 -4
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
> Source snapshot: official ti.admob.unified 1.0.0 documentation at commit `5b4cbf9` (copied 2026-10-11). Relative links rebased for this skill.
|
|
2
|
+
|
|
3
|
+
# Changelog
|
|
4
|
+
|
|
5
|
+
## [1.0.0] — Unreleased
|
|
6
|
+
|
|
7
|
+
### Audit corrections
|
|
8
|
+
|
|
9
|
+
- Normalize iOS load errors to the shared constants and return actual Booleans through the bridge.
|
|
10
|
+
- Implement percentage-based application volume on iOS and validate the same range on Android.
|
|
11
|
+
- Hide accidental iOS state/helper exports while preserving native delegates and lifecycle callbacks.
|
|
12
|
+
- Expose fullscreen configuration properties on Android and retain primitive extras; defer banner reconfiguration to its next load.
|
|
13
|
+
- Allow consent retries after failures, refresh cached results after privacy options, and serialize reset with outstanding UMP work.
|
|
14
|
+
- Read Android's standard IAB preferences and restrict mediation availability to installed adapters.
|
|
15
|
+
- Capture the presented rewarded ad's reward independently of dismissal/reload; serialize fullscreen SDK operations on the UI thread.
|
|
16
|
+
- Remove targeting values and test-device IDs from module-owned debug messages.
|
|
17
|
+
- Fix library callback reentrancy, share concurrent privacy/Inspector operations, and wait for iOS adaptive layout.
|
|
18
|
+
- Keep banner-button feedback in the button with light-green styling; reuse the current banner on reload without collapsing its slot.
|
|
19
|
+
- Keep ads and listeners through an Android light/dark switch: the example and the cleanup guide ignore the `close` event Titanium fires while it recreates the activity.
|
|
20
|
+
- Check fullscreen request dimensions at Show in the library and playground; reload only the selected stale ad, without rotation listeners or timers.
|
|
21
|
+
- Accept iOS UMP UUID test identifiers and support per-platform consent test defaults in the example application's properties.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
First public release. Earlier development snapshots were not published releases.
|
|
25
|
+
|
|
26
|
+
### Dependency refresh
|
|
27
|
+
|
|
28
|
+
- Update Google Mobile Ads to iOS 13.10.0 and Android 25.5.0; UMP remains at iOS 3.1.0 and Android 4.0.0.
|
|
29
|
+
- Update all five adapters to the September 23, 2026 published versions listed in [Dependencies](dependencies.md).
|
|
30
|
+
- Remove IronSourceAdQualitySDK from Unity: Unity Ads 4.20.1 no longer depends on it.
|
|
31
|
+
- Pin Guava 33.7.1-android in the core and OkHttp 4.12.0 in InMobi/Liftoff to replace the Guava, OkHttp and Okio versions flagged in the security review.
|
|
32
|
+
- Retain the version contract test: Meta now matches across platforms; Liftoff retains the documented SDK difference.
|
|
33
|
+
|
|
34
|
+
### Unified core
|
|
35
|
+
|
|
36
|
+
- One iOS/Android JavaScript API for standard/adaptive banners, interstitials, rewarded ads and app open ads.
|
|
37
|
+
- Consent-first UMP flow, portable ATT completion and Ad Inspector support.
|
|
38
|
+
- Idempotent initialization, serialized loads and deterministic cleanup.
|
|
39
|
+
- Google Mobile Ads and UMP only; no third-party network adapters in the core.
|
|
40
|
+
- The examples use only the core without a mediation flag. Google Mobile Ads automatically discovers adapters supplied by selected complements; `disableMediation: true` remains an explicit session exception.
|
|
41
|
+
|
|
42
|
+
### Optional mediation
|
|
43
|
+
|
|
44
|
+
- Five independent dependency modules: `ti.admob.unified.mediation.applovin`, `.meta`, `.inmobi`, `.unity` and `.liftoff`, each on Android and iOS at `1.0.0`.
|
|
45
|
+
- Each Android complement declares only its adapter Maven coordinate. Each iOS complement vendors only its own adapter, SDK and required resources/dependencies.
|
|
46
|
+
- Unity includes UnityAdapter, UnityAds and UnityCoherenceLib. Its updated SDK no longer requires IronSourceAdQualitySDK.
|
|
47
|
+
- ironSource mediation is deferred; IronSourceAdapter and IronSource are not distributed.
|
|
48
|
+
- SDKs and adapters were updated to the published September 23, 2026 versions; framework checksums were regenerated. See [Dependencies](dependencies.md).
|
|
49
|
+
- `getMediationStatus()` returns generic Google initialization diagnostics; pre-release provider probes and no-op consent setters were removed. `disableMediation` remains a global startup control.
|
|
50
|
+
- Release artifacts are discovered from complement folders and manifests; packaged dependencies are checked against literal Gradle declarations without a provider list. Nothing is published or tagged by the build scripts.
|
|
51
|
+
|
|
52
|
+
### Validation
|
|
53
|
+
|
|
54
|
+
Packaging/linking and Google test-ad loading are separate from third-party ad delivery. Provider delivery requires configured accounts, mappings and Ad Inspector evidence; it is not established by a successful build or a Google test ad. See [release validation](mediation.md#release-validation).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 César Estrada
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
> Source snapshot: official ti.admob.unified 1.0.0 documentation at commit `5b4cbf9` (copied 2026-10-11). Relative links rebased for this skill.
|
|
2
|
+
|
|
3
|
+
# Privacy and initialization
|
|
4
|
+
|
|
5
|
+
`ti.admob.unified` exposes Google UMP as an event-based workflow. Callback properties are not part of the contract.
|
|
6
|
+
|
|
7
|
+
## Required order
|
|
8
|
+
|
|
9
|
+
Use this order on every app launch:
|
|
10
|
+
|
|
11
|
+
1. Register module listeners.
|
|
12
|
+
2. Call `requestConsent({ ... })`.
|
|
13
|
+
3. Wait for the terminal `consent_complete` event.
|
|
14
|
+
4. Check `event.canRequestAds` or `canRequestAds()`.
|
|
15
|
+
5. Call `initialize({ ... })` once.
|
|
16
|
+
6. Create and load ads only after initialization succeeds.
|
|
17
|
+
|
|
18
|
+
App Tracking Transparency is optional and separate from UMP. `canRequestAds()` remains the only ad-request gate. If the application uses tracking, resolve ATT before `initialize()`; otherwise skip it. See [Optional: if the application requests ATT](getting-started.md#optional-if-the-application-requests-att).
|
|
19
|
+
|
|
20
|
+
Check UMP even when the consent operation reports an error. Consent from a previous session may still allow requests; `canRequestAds` determines whether the application can continue.
|
|
21
|
+
|
|
22
|
+
Google's UMP guidance also requires a consent-information update every app session and warns against deriving status from cached consent strings. See [UMP for Android](https://developers.google.com/admob/android/privacy) and [UMP for iOS](https://developers.google.com/admob/ios/privacy).
|
|
23
|
+
|
|
24
|
+
## `requestConsent(config)`
|
|
25
|
+
|
|
26
|
+
Starts the UMP consent-information update and immediately loads/presents a form if one is required.
|
|
27
|
+
|
|
28
|
+
| Property | Type | Default | Description |
|
|
29
|
+
| ------------------------- | -------- | -------------- | ---------------------------------------------------------------------- |
|
|
30
|
+
| `geography` | Number | Native default | A `DEBUG_GEOGRAPHY_*` constant. Development only. |
|
|
31
|
+
| `testDeviceIds` | String[] | `[]` | UMP hashed test-device identifiers. Used when `geography` is supplied. |
|
|
32
|
+
| `tagForUnderAgeOfConsent` | Boolean | `false` | Marks the consent request as under age of consent. |
|
|
33
|
+
|
|
34
|
+
Use `{}` when no options are needed:
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
Admob.requestConsent({})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The operation is idempotent:
|
|
41
|
+
|
|
42
|
+
- Concurrent calls share the active native operation.
|
|
43
|
+
- The first accepted call supplies the configuration.
|
|
44
|
+
- A later call after completion re-emits the cached `consent_complete` result.
|
|
45
|
+
- `resetConsent()` clears UMP test state and the module's cached consent operation so a new request can run.
|
|
46
|
+
|
|
47
|
+
Do not put `resetConsent()` in a production launch path.
|
|
48
|
+
|
|
49
|
+
## `consent_complete`
|
|
50
|
+
|
|
51
|
+
Every accepted consent operation reaches this terminal event:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
{
|
|
55
|
+
success: true,
|
|
56
|
+
canRequestAds: true,
|
|
57
|
+
privacyOptionsRequired: false
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
On failure:
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
{
|
|
65
|
+
success: false,
|
|
66
|
+
canRequestAds: false,
|
|
67
|
+
privacyOptionsRequired: false,
|
|
68
|
+
error: 'Native UMP error message',
|
|
69
|
+
code: 1
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The exact native `code` is platform and SDK dependent. Do not make business logic depend on a particular code.
|
|
74
|
+
|
|
75
|
+
The payload temporarily retains these deprecated keys:
|
|
76
|
+
|
|
77
|
+
- `canShowAds`
|
|
78
|
+
- `canShowPersonalizedAds`
|
|
79
|
+
- `isGDPR`
|
|
80
|
+
- `isPrivacyOptionsRequired`
|
|
81
|
+
|
|
82
|
+
New code must use `canRequestAds` and `privacyOptionsRequired`.
|
|
83
|
+
|
|
84
|
+
The legacy `consent_ready` and `consent_error` events are emitted before the modern terminal event for compatibility. Do not subscribe to all three for the same workflow or initialization may be attempted more than once.
|
|
85
|
+
|
|
86
|
+
## `canRequestAds()`
|
|
87
|
+
|
|
88
|
+
Returns UMP's current permission to request ads.
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
if (Admob.canRequestAds()) {
|
|
92
|
+
// An ad request may be made.
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This is the only supported request gate.
|
|
97
|
+
|
|
98
|
+
- `canShowAds()` is a deprecated alias.
|
|
99
|
+
- `canShowPersonalizedAds()` is deprecated and always returns `false`.
|
|
100
|
+
- `isGDPR()` is a legacy diagnostic and must not gate ads.
|
|
101
|
+
- Do not parse `IABTCF_*` storage.
|
|
102
|
+
- Do not derive or inject an `npa` request flag from these legacy methods.
|
|
103
|
+
|
|
104
|
+
Google Mobile Ads applies the privacy signals collected by UMP.
|
|
105
|
+
|
|
106
|
+
## `initialize(config)`
|
|
107
|
+
|
|
108
|
+
Configures the global Google Mobile Ads request settings and initializes the SDK.
|
|
109
|
+
|
|
110
|
+
| Property | Type | Description |
|
|
111
|
+
| ------------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
112
|
+
| `testDeviceIds` | String[] | Google Mobile Ads test-device identifiers. |
|
|
113
|
+
| `ageRestrictedTreatment` | String | One `AGE_RESTRICTED_TREATMENT_*` constant. |
|
|
114
|
+
| `maxAdContentRating` | String | One `MAX_AD_CONTENT_RATING_*` constant. |
|
|
115
|
+
| `tagForChildDirectedTreatment` | Boolean | Deprecated compatibility input; maps to child/unspecified. |
|
|
116
|
+
| `tagForUnderAgeOfConsent` | Boolean | Deprecated initialization input; maps to child/unspecified. This is distinct from the UMP option with the same name. |
|
|
117
|
+
|
|
118
|
+
`applicationId` and `debugGeography` are not initialization properties.
|
|
119
|
+
|
|
120
|
+
Initialization is idempotent:
|
|
121
|
+
|
|
122
|
+
- Concurrent calls share one native operation.
|
|
123
|
+
- The first accepted configuration wins.
|
|
124
|
+
- A call after completion re-emits the cached `module_initialized` result.
|
|
125
|
+
- An Android failure caused by a missing current activity can be retried.
|
|
126
|
+
|
|
127
|
+
### `module_initialized`
|
|
128
|
+
|
|
129
|
+
Success:
|
|
130
|
+
|
|
131
|
+
```js
|
|
132
|
+
{
|
|
133
|
+
success: true,
|
|
134
|
+
status: 'Native initialization status description'
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Android can report a missing-activity failure:
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
{
|
|
142
|
+
success: false,
|
|
143
|
+
error: 'No current activity',
|
|
144
|
+
code: -1
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Use `status` for diagnostics. Its text is not a stable machine-readable value.
|
|
149
|
+
|
|
150
|
+
## App Tracking Transparency
|
|
151
|
+
|
|
152
|
+
`requestTrackingAuthorization()` is available on both platforms and emits:
|
|
153
|
+
|
|
154
|
+
```js
|
|
155
|
+
{
|
|
156
|
+
status: 3,
|
|
157
|
+
authorized: true,
|
|
158
|
+
applicable: true
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
On iOS, the numeric status follows Apple's `ATTrackingManagerAuthorizationStatus`:
|
|
163
|
+
|
|
164
|
+
| Value | Meaning |
|
|
165
|
+
| ----: | -------------- |
|
|
166
|
+
| `0` | Not determined |
|
|
167
|
+
| `1` | Restricted |
|
|
168
|
+
| `2` | Denied |
|
|
169
|
+
| `3` | Authorized |
|
|
170
|
+
|
|
171
|
+
On Android, ATT does not apply. The method completes synchronously with `status: 3`, `authorized: true`, and `applicable: false`, allowing the same listener and call site on both platforms.
|
|
172
|
+
|
|
173
|
+
Always wait for `tracking_authorization_completed`, even if the user resolved ATT in an earlier session. Denial changes tracking availability and does not imply `canRequestAds() === false`; UMP still determines permission to request ads.
|
|
174
|
+
|
|
175
|
+
ATT is optional. An application that calls `requestTrackingAuthorization()` must ship `NSUserTrackingUsageDescription` in its plist, because Apple's prompt cannot be presented without one. An application that never calls it should omit the key: Apple reviews the prompt against actual behavior, and UMP works without it. See [Getting started](getting-started.md#ios).
|
|
176
|
+
|
|
177
|
+
## Privacy options
|
|
178
|
+
|
|
179
|
+
After consent completes, use either the event payload or `isPrivacyOptionsRequired()` to decide whether the app should show a visible, interactive privacy entry point:
|
|
180
|
+
|
|
181
|
+
```js
|
|
182
|
+
privacyButton.visible = Admob.isPrivacyOptionsRequired()
|
|
183
|
+
privacyButton.touchEnabled = privacyButton.visible
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
When the user taps it:
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
const onPrivacyDismissed = event => {
|
|
190
|
+
if (!event.success) {
|
|
191
|
+
Ti.API.warn(`Privacy options failed: ${event.error}`)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
privacyButton.visible = event.privacyOptionsRequired
|
|
195
|
+
privacyButton.touchEnabled = privacyButton.visible
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
Admob.addEventListener('privacy_options_dismissed', onPrivacyDismissed)
|
|
199
|
+
|
|
200
|
+
privacyButton.addEventListener('click', () => {
|
|
201
|
+
Admob.presentPrivacyOptions({})
|
|
202
|
+
})
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
The event payload is:
|
|
206
|
+
|
|
207
|
+
```js
|
|
208
|
+
{
|
|
209
|
+
success: true,
|
|
210
|
+
canRequestAds: true,
|
|
211
|
+
privacyOptionsRequired: true
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Failures add `error` and `code`. Remove the module listener when its owning service is disposed.
|
|
216
|
+
|
|
217
|
+
## Testing UMP
|
|
218
|
+
|
|
219
|
+
Use debug geography only with registered UMP test devices:
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
Admob.requestConsent({
|
|
223
|
+
geography: Admob.DEBUG_GEOGRAPHY_EEA,
|
|
224
|
+
testDeviceIds: ['HASHED_UMP_TEST_DEVICE_ID'],
|
|
225
|
+
tagForUnderAgeOfConsent: false
|
|
226
|
+
})
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Available debug constants:
|
|
230
|
+
|
|
231
|
+
- `DEBUG_GEOGRAPHY_DISABLED`
|
|
232
|
+
- `DEBUG_GEOGRAPHY_EEA`
|
|
233
|
+
- `DEBUG_GEOGRAPHY_REGULATED_US_STATE`
|
|
234
|
+
- `DEBUG_GEOGRAPHY_OTHER`
|
|
235
|
+
|
|
236
|
+
Do not store the numeric values; use the names because the native enum values are platform-owned.
|
|
237
|
+
|
|
238
|
+
`resetConsent()` exists for controlled testing. It does not remove the need to request consent information again, and it must not be exposed as a general "revoke consent" implementation. Use `presentPrivacyOptions()` for the publisher-rendered privacy entry point.
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
## Interactive consent demo
|
|
242
|
+
|
|
243
|
+
The published `example/app.js` includes **Consent demo** controls in development/test builds on Android and iOS. First launch uses the normal region. Production builds hide these controls and ignore saved debug settings.
|
|
244
|
+
|
|
245
|
+
1. In the visible **Test device** field, use the physical device's UMP identifier from the SDK log, including any hyphens on iOS; the app remembers it. To prefill a development build, set the string application property `demo.consentDeviceIds.ios` or `demo.consentDeviceIds.android` in the consumer's `tiapp.xml`. A saved nonempty field takes precedence. iOS simulators need no identifier. Enter only finishes typing.
|
|
246
|
+
2. Tap the scenario selector, choose **Europe — consent form**, **US — privacy options**, **Other region — no form**, or **My actual region**, then tap **Run test**. Selecting a scenario alone does not reset consent. Running it clears the previous UMP choice and replaces existing ads.
|
|
247
|
+
3. The single result below the button reports progress and completion. Europe requests consent; US opens privacy options when available; Other and the actual region can finish without a dialog. Which form is available depends on the AdMob message configuration. The banner slot keeps its height while ads reload.
|
|
248
|
+
4. Use **Advertising privacy options** to revise a choice without resetting. Relaunching preserves the chosen mode, hashes and consent. Run **My actual region** to remove the region override.
|
|
249
|
+
|
|
250
|
+
Demo ad unit IDs do not register physical devices for UMP debugging. If the SDK log redacts the hash, use an iOS simulator; an unregistered physical device may ignore forced geography.
|
|
251
|
+
|
|
252
|
+
These test buttons reset UMP consent only. They cannot reset Apple's ATT permission. Do not copy these testing controls or debug geography into a production consent flow. Unknown/error states are displayed separately from a successful result that does not require privacy options.
|
|
253
|
+
|
|
254
|
+
Google reference: [Testing UMP on iOS](https://developers.google.com/admob/ios/privacy#testing) and [Testing UMP on Android](https://developers.google.com/admob/android/privacy#testing).
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
> Source snapshot: official ti.admob.unified 1.0.0 documentation at commit `5b4cbf9` (copied 2026-10-11). Relative links rebased for this skill.
|
|
2
|
+
|
|
3
|
+
# ti.admob.unified roadmap
|
|
4
|
+
|
|
5
|
+
## Current baseline
|
|
6
|
+
|
|
7
|
+
Version `1.0.0` establishes one portable AdMob distribution with five optional mediation complements:
|
|
8
|
+
|
|
9
|
+
- Titanium `13.2.0.GA`
|
|
10
|
+
- iOS `15.0+`
|
|
11
|
+
- Google Mobile Ads iOS `13.10.0`
|
|
12
|
+
- User Messaging Platform iOS `3.1.0`
|
|
13
|
+
- Android API `24+`, the floor the Titanium module template sets
|
|
14
|
+
- Google Mobile Ads Android `25.5.0`
|
|
15
|
+
- User Messaging Platform Android `4.0.0`
|
|
16
|
+
- five optional per-network modules on iOS and Android; ironSource mediation deferred
|
|
17
|
+
- idempotent initialization and consent
|
|
18
|
+
- terminal `consent_complete` events
|
|
19
|
+
- one standard/adaptive banner lifecycle on both platforms
|
|
20
|
+
- one interstitial/rewarded/app open lifecycle and event contract on both platforms
|
|
21
|
+
- portable tracking-authorization completion on both platforms
|
|
22
|
+
- no manual TCF personalization inference
|
|
23
|
+
|
|
24
|
+
## Implemented for 1.0.0
|
|
25
|
+
|
|
26
|
+
### Privacy contract
|
|
27
|
+
|
|
28
|
+
- `canRequestAds()` is the only supported ad-request gate.
|
|
29
|
+
- UMP updates and form presentation use the current native flow.
|
|
30
|
+
- `initialize()` and `requestConsent()` serialize concurrent calls.
|
|
31
|
+
- Every accepted consent operation reaches `consent_complete`.
|
|
32
|
+
- Privacy-options dismissal always emits a terminal event.
|
|
33
|
+
- `requestTrackingAuthorization()` is portable after UMP: iOS resolves ATT and Android completes immediately with `applicable: false`.
|
|
34
|
+
- Legacy privacy aliases remain documented but are not used by new examples.
|
|
35
|
+
|
|
36
|
+
### Banner contract
|
|
37
|
+
|
|
38
|
+
- Standard and adaptive banners expose `load()`, `pause()`, `resume()`, `destroy()`, `isLoaded()`, and both historical destruction aliases.
|
|
39
|
+
- Common event names and payload keys are aligned.
|
|
40
|
+
- Adaptive `loaded` reports the real height in density-independent units.
|
|
41
|
+
- `destroy()` is terminal, repeatable, and emits `destroyed` once.
|
|
42
|
+
- Native delegates, listeners, controllers, views, and activity lifecycle registrations are released.
|
|
43
|
+
- Each proxy accepts one active load and at most one deferred load while paused.
|
|
44
|
+
- Application and host-lifecycle pauses are independent causes; neither resumes the other's pause.
|
|
45
|
+
- Inline adaptive banners, `maxHeight`, `customAdSize`, `contentUrl`, and `requestAgent` work on both platforms.
|
|
46
|
+
- `smart_banner` resolves to `BANNER` on both platforms, with no special case on either.
|
|
47
|
+
|
|
48
|
+
### Fullscreen contract
|
|
49
|
+
|
|
50
|
+
- Interstitial, rewarded, and app open proxies expose the same `load()`, `show()`, `isLoaded()`, and terminal `destroy()` lifecycle.
|
|
51
|
+
- Duplicate loads are serialized and native fullscreen references are single-use.
|
|
52
|
+
- Common events include `adUnitId` and `adType`; failures add `error`, `message`, and `code`.
|
|
53
|
+
- Both platforms emit `opened`, `showed_fullscreen_content`, and `destroyed`.
|
|
54
|
+
- Native callbacks/delegates are detached during explicit destruction and Titanium proxy release.
|
|
55
|
+
- App open checks Google's four-hour validity window on demand, without a timer.
|
|
56
|
+
|
|
57
|
+
### Distribution
|
|
58
|
+
|
|
59
|
+
- The `ti.admob.unified` artifacts contain Google Mobile Ads and UMP alone: ~14 MB on iOS, ~325 KB on Android, and no network SDK in the consuming application's POM.
|
|
60
|
+
- Five dependency modules under `mediation/<network>/` distribute eleven iOS frameworks and five Android adapter coordinates. Unity includes Coherence; neither AdQuality nor ironSource advertising is included.
|
|
61
|
+
- Dependency versions and iOS checksums are reproducible.
|
|
62
|
+
- Static contract tests cover privacy, lifecycle, payload, cleanup, artifacts, and documentation.
|
|
63
|
+
|
|
64
|
+
## Release readiness
|
|
65
|
+
|
|
66
|
+
The September 2026 audit distinguishes module behavior, consumer integration and provider delivery. A successful build or Google test banner proves neither third-party delivery nor all privacy scenarios.
|
|
67
|
+
|
|
68
|
+
The correction pass now has executable coverage for library cleanup and reentrant retries, consent reset ordering, percentage volume validation and delayed reward callbacks. Both native bridges returned the expected Boolean types and loaded all five implemented formats. Repeated banner taps preserved the scroll position in the Android emulator. Three physical-iPad launches loaded the adaptive banner at 810 × 150 and all three fullscreen formats; the earlier startup sizing failure did not recur, but its cause has not been isolated.
|
|
69
|
+
|
|
70
|
+
Remaining acceptance work:
|
|
71
|
+
|
|
72
|
+
- record fullscreen dismissal and actual reward delivery separately from load and presentation;
|
|
73
|
+
- cover consent acceptance/rejection, privacy reopening, ATT states and orientation/lifecycle changes on the available devices;
|
|
74
|
+
- retain the intermittent iOS Rewarded timeout and its UIKit reproduction until a reproducible SDK/runtime resolution is established;
|
|
75
|
+
- verify provider-side consent propagation and review the updated transitive dependency results in [Dependencies](dependencies.md#transitive-security-review);
|
|
76
|
+
- validate intended mediation providers with configured accounts, mappings and Ad Inspector. Core-only applications need no provider accounts.
|
|
77
|
+
|
|
78
|
+
The declared minimum OS versions and complete physical-device interaction matrix remain unverified. Simulator and emulator evidence is recorded separately. No additional device purchase is required to continue independent checks.
|
|
79
|
+
|
|
80
|
+
## Next contract work
|
|
81
|
+
|
|
82
|
+
These improvements can be developed without changing the established banner and privacy APIs:
|
|
83
|
+
|
|
84
|
+
- keep the shared percentage-based `setAppVolume()` behavior covered on both platforms;
|
|
85
|
+
- remove deprecated privacy and destruction aliases in a future major release.
|
|
86
|
+
|
|
87
|
+
## Declared parity debt
|
|
88
|
+
|
|
89
|
+
Both platforms must expose an identical JavaScript surface. An audit against the native sources on 5 August 2026 found the divergences below. That pass recorded them as closed based largely on static tests. The September audit reopened cases involving bridge types and accidental exports. The table below is historical context; release acceptance requires runtime verification of the current binaries.
|
|
90
|
+
|
|
91
|
+
| Divergence closed | How |
|
|
92
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
93
|
+
| `requestAgent` was dropped by the three iOS fullscreen proxies. Their manual configuration from the creation dictionary bypasses `_initWithProperties:` and never read the key. | `configureWithDict:` reads it in all three, mirroring Android. |
|
|
94
|
+
| `extras` was a live property on iOS and creation-only on Android: assigning it after creating a banner did nothing, and reading it back returned `undefined`. | Both Android banner proxies gained the property. It takes effect on the next `load()`, the same as `requestAgent`. |
|
|
95
|
+
| The adaptive `loaded` payload carried seven size keys on Android and two on iOS. | iOS reports the same seven. `density` comes from `UIScreen.scale`, which yields only 1, 2 or 3 where Android reports fractional values. |
|
|
96
|
+
| Fullscreen proxies exposed their internal state as readable properties on iOS and none on Android, including the native handle (`GADInterstitialAd`). | Plain ivars with `accessInstanceVariablesDirectly` disabled, so Kroll's key lookup finds nothing. |
|
|
97
|
+
| `collapsible` was Android-only. | Implemented on iOS through `GADExtras`, the same key and values Android puts in its Bundle. |
|
|
98
|
+
| iOS filtered banner events by whether a listener was registered; Android emitted them unconditionally. | The guard is gone. Banner proxies descend from `TiViewProxy`, so the events reach a listener on the container. |
|
|
99
|
+
| `DEBUG_GEOGRAPHY_OTHER` returned the deprecated `UMPDebugGeographyNotEEA` (2) on iOS while Android sent 4, and `DEBUG_GEOGRAPHY_REGULATED_US_STATE` was the literal `@(3)`. | Both return the SDK enum, which matches Android's values. |
|
|
100
|
+
| iOS substituted `"coins"` and `1` when the SDK granted a reward with no values, so an application could credit a reward Android never granted. | The payload carries what the SDK reported, or `null`. |
|
|
101
|
+
| iOS `resume()` never restored `autoloadEnabled` after `pause()` turned it off, so one trip to the background left the banner opted out for the rest of the session. | `pause()` remembers the value and `resume()` restores it, once every pause cause is clear. |
|
|
102
|
+
| Adaptive events fired by the Android proxy itself omitted `adaptiveType`, which the view included. | Every adaptive event carries it. |
|
|
103
|
+
|
|
104
|
+
## Differences that stay
|
|
105
|
+
|
|
106
|
+
The following differences are classified as SDK limitations and are documented where relevant. They are not scheduled for correction:
|
|
107
|
+
|
|
108
|
+
| Difference | Why it stays |
|
|
109
|
+
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
110
|
+
| `module_initialized` has no error branch | Neither SDK reports one. `GADInitializationStatus` carries no error, and Android's callback has no failure path either; its only `success: false` is a missing-Activity pre-check. |
|
|
111
|
+
| `applicable` in `tracking_authorization_completed` | App Tracking Transparency does not exist on Android. |
|
|
112
|
+
| The values of the `TEST_*` constants | They are Google's own demo unit IDs, deliberately different per platform. |
|
|
113
|
+
| `isTestDevice()` | iOS answers "are any test devices registered?", Android "is this device one?". The iOS SDK does not offer the second. |
|
|
114
|
+
| The text of error messages | Load errors use shared constants; presentation/UMP/Inspector codes retain their native domains. The text describes the platform failure ("no view controller" against "no activity"). |
|
|
115
|
+
|
|
116
|
+
## Deferred formats
|
|
117
|
+
|
|
118
|
+
- Rewarded interstitial
|
|
119
|
+
- Native
|
|
120
|
+
|
|
121
|
+
Their constants are already exported, but they do not have working cross-platform factories. Implementing one requires a complete native proxy, shared events and payloads, cleanup semantics, tests, examples, and physical validation.
|
|
122
|
+
|
|
123
|
+
These formats remain to be implemented to match the modules this one replaces. As of 4 August 2026: `ti.android.admob` `11.1.0` ships proxies for app open, rewarded interstitial and native, and `ti.admob` `8.1.0` on iOS documents an `AD_TYPE_APP_OPEN`. App open ships here on both platforms, which leaves rewarded interstitial and native.
|
|
124
|
+
|
|
125
|
+
Decided on 4 August 2026:
|
|
126
|
+
|
|
127
|
+
- Rewarded interstitial is planned next. App open came first because it was the only format present in both replaced modules.
|
|
128
|
+
- Native remains deferred because none of the applications in progress has a content list that needs ads styled as list items. The decision reflects current use cases, rather than implementation difficulty. A future app with a content feed would justify reconsidering it.
|
|
129
|
+
|
|
130
|
+
Each new format must meet the existing contract: a complete native proxy on both platforms, shared events and payloads, terminal cleanup, contract tests, an example, and physical validation.
|
|
131
|
+
|
|
132
|
+
## Mediation maintenance
|
|
133
|
+
|
|
134
|
+
The five complements live in `mediation/<network>/` and target the same first release, `1.0.0`, as the core.
|
|
135
|
+
|
|
136
|
+
- Keep the five shared adapter/network SDK pairs current on both platforms.
|
|
137
|
+
- Keep every adapter out of the core module. A contract test fails if `ios/module.xcconfig`, `android/build.gradle`, the core `pbxproj`, or the core checksum inventory names a network again.
|
|
138
|
+
- Preserve one JavaScript ad contract and portable diagnostics.
|
|
139
|
+
- Track privacy manifests, resource bundles, SKAdNetwork guidance, and store disclosure changes with every dependency update.
|
|
140
|
+
- Require consumer builds, physical-device tests, and Ad Inspector evidence before release: record hardware evidence separately from simulator integration and Google test ads.
|
|
141
|
+
- Evaluate additional networks only when they can be supported on both platforms without fragmenting the public API.
|
|
142
|
+
|
|
143
|
+
## Longer-term platform work
|
|
144
|
+
|
|
145
|
+
- Evaluate Android Google Mobile Ads Next-Gen only after its migration cost and Titanium compatibility are understood.
|
|
146
|
+
- Revisit the minimum Titanium, iOS, and Android baselines as upstream SDK requirements change.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Official sources and snapshot maintenance
|
|
2
|
+
|
|
3
|
+
The native module is `ti.admob.unified`; this skill is `ti-admob-unified`. It works in ordinary Titanium apps as well as games and does not depend on `ti.game`, `ti.synthengine` or PurgeTSS.
|
|
4
|
+
|
|
5
|
+
## Provenance
|
|
6
|
+
|
|
7
|
+
Copied from César's module repository `macCesar/ti.admob.unified`, at clean commit `5b4cbf9347a51c4f959dc262ac1500f82f28b4a0` on 2026-10-11. The source checkout in this workspace is `/Users/cesar/Developer/openSource/TiAdmobUnified/ti.admob.unified`; use the installed package's documentation or the module's actual repository in other environments, not that machine-specific path as a dependency. The 1.0.0 first public release remains under preparation according to this session; re-check its release status when installing later.
|
|
8
|
+
|
|
9
|
+
`source-snapshot.json` records original paths, source SHA-256, destination hashes and rebased Markdown links. Eleven official `documentation/*.md` guides are preserved, with dependency inventory, roadmap, contributing guide, upstream changelog and module license. Each Markdown file adds a source line and rewrites relative links (with any separately recorded broken-anchor correction) so they resolve inside the skill. Long API/banner references add generated TOCs. This provenance applies to the copied references, not to TiTools' curated `game-monetization.md` or this note.
|
|
10
|
+
|
|
11
|
+
`assets/example/lib/ads.js`, `assets/example/library-usage.js` and `assets/example/app.js` are byte-identical official source files. They are application code resources, not scripts to run in Node for ad delivery. The library is intended to be copied unchanged into the consuming app; keep project policies in a separate director/controller. Review native integration on both target platforms.
|
|
12
|
+
|
|
13
|
+
## Source priority and updates
|
|
14
|
+
|
|
15
|
+
Use the installed native module/build and its official docs for actual APIs and parity. This snapshot is a reproducible source for the documented 1.0.0 contract, not a proof of native ad delivery. A newer local build can carry behavior ahead of a version label; reconcile documented methods with installed artifacts before changing integration.
|
|
16
|
+
|
|
17
|
+
When updating the skill, inspect source changes and repository state, copy the official docs/example library, rebase all local links, regenerate only the affected TOCs, and update source and destination hashes. Keep the copy-ready library untouched. Run TiTools manifest, anchor, snapshot/link and example syntax tests; check packaging and installability. Validate integration and selected-provider delivery independently when a device/accounts are available. Do not silently refresh only version labels or hashes around unreviewed API changes.
|
|
18
|
+
|
|
19
|
+
Provider accounts, mediation groups, credentials, placement mappings and network privacy settings live outside a successful compile. `getMediationStatus()` describes Google's adapter initialization map, not installation inventory or delivery. Use the official mediation guide, current linked Google/provider setup documents, and single-source Ad Inspector testing. A Google demo ad cannot validate AppLovin/Meta/InMobi/Unity/Liftoff demand.
|
|
20
|
+
|
|
21
|
+
## TiTools audit convention
|
|
22
|
+
|
|
23
|
+
The maintainer-only `titools-skill-auditor` source map registers this skill. Use its quality/coverage workflow for future updates, including reading every affected official source, reporting docs/native disagreements and preserving verified author additions. The title `## Community-Discovered Patterns` denotes protected content; do not remove it merely because official docs do not mention it. Update or move it when official docs gain equivalent coverage. Creation of this new skill follows the authorized skill-creator task rather than reopening an audit approval gate.
|
|
24
|
+
|
|
25
|
+
Before an update run this maintainer tool from the TiTools repository:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
node scripts/verify-module-snapshot.mjs --source /path/to/ti.admob.unified
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
It reports changed/missing sources, newly added official Markdown, modified shipped mirrors, source dirtiness and commit changes. It performs no fetch, pull, write or hash refresh. Compare the pinned commit to the candidate commit, review the report and relevant native/library changes, then perform only the authorized update. Native-module releases, provider SDK changes and official-doc corrections can all trigger a review.
|
|
32
|
+
|
|
33
|
+
Snapshot link correction: the official API page still links to `#mediation-diagnostics-and-compatibility` after its heading became `Mediation diagnostics`. The mirrored link targets `#mediation-diagnostics`; `source-snapshot.json` records the exact transformation and tests reconstruct the original source hash. The module repository was not edited. Re-check this correction during the next refresh.
|