@maccesar/titools 2.0.6 → 2.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/{AGENTS-TEMPLATE.md → AGENTS-VERCEL-RESEARCH.md} +16 -18
- package/README.md +250 -168
- package/agents/{ti-researcher.md → ti-pro.md} +10 -10
- package/bin/titools.js +16 -12
- package/lib/cleanup.js +95 -0
- package/lib/commands/agents.js +146 -70
- package/lib/commands/skills.js +349 -0
- package/lib/commands/uninstall.js +189 -154
- package/lib/commands/update.js +104 -21
- package/lib/config.js +26 -20
- package/lib/downloader.js +1 -1
- package/lib/installer.js +37 -97
- package/lib/platform.js +9 -5
- package/lib/prompts/checkboxCancel.js +264 -0
- package/lib/prompts/selectCancel.js +204 -0
- package/lib/symlink.js +19 -7
- package/lib/utils.js +21 -31
- package/package.json +10 -10
- package/skills/alloy-guides/SKILL.md +8 -30
- package/skills/alloy-guides/references/CLI_TASKS.md +14 -24
- package/skills/alloy-guides/references/CONCEPTS.md +5 -25
- package/skills/alloy-guides/references/CONTROLLERS.md +2 -19
- package/skills/alloy-guides/references/MODELS.md +40 -10
- package/skills/alloy-guides/references/PURGETSS.md +1 -11
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +8 -14
- package/skills/alloy-guides/references/VIEWS_STYLES.md +14 -25
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +2 -8
- package/skills/alloy-guides/references/VIEWS_XML.md +29 -40
- package/skills/alloy-guides/references/WIDGETS.md +1 -17
- package/skills/alloy-howtos/SKILL.md +1 -22
- package/skills/alloy-howtos/references/best_practices.md +0 -17
- package/skills/alloy-howtos/references/cli_reference.md +1 -23
- package/skills/alloy-howtos/references/config_files.md +86 -15
- package/skills/alloy-howtos/references/custom_tags.md +14 -13
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +3 -22
- package/skills/alloy-howtos/references/samples.md +4 -14
- package/skills/purgetss/SKILL.md +11 -37
- package/skills/purgetss/references/EXAMPLES.md +106 -17
- package/skills/purgetss/references/animation-system.md +0 -67
- package/skills/purgetss/references/apply-directive.md +0 -18
- package/skills/purgetss/references/arbitrary-values.md +0 -25
- package/skills/purgetss/references/class-index.md +0 -46
- package/skills/purgetss/references/cli-commands.md +0 -41
- package/skills/purgetss/references/configurable-properties.md +0 -55
- package/skills/purgetss/references/custom-rules.md +0 -14
- package/skills/purgetss/references/customization-deep-dive.md +0 -49
- package/skills/purgetss/references/dynamic-component-creation.md +56 -37
- package/skills/purgetss/references/grid-layout.md +0 -32
- package/skills/purgetss/references/icon-fonts.md +0 -50
- package/skills/purgetss/references/installation-setup.md +61 -32
- package/skills/purgetss/references/migration-guide.md +127 -0
- package/skills/purgetss/references/opacity-modifier.md +0 -34
- package/skills/purgetss/references/performance-tips.md +261 -0
- package/skills/purgetss/references/platform-modifiers.md +0 -46
- package/skills/purgetss/references/smart-mappings.md +0 -12
- package/skills/purgetss/references/tikit-components.md +393 -0
- package/skills/purgetss/references/titanium-resets.md +1 -27
- package/skills/purgetss/references/ui-ux-design.md +467 -117
- package/skills/{alloy-expert → ti-expert}/SKILL.md +45 -54
- package/skills/ti-expert/references/alloy-builtins.md +387 -0
- package/skills/{alloy-expert → ti-expert}/references/alloy-structure.md +147 -40
- package/skills/ti-expert/references/anti-patterns.md +90 -0
- package/skills/ti-expert/references/cli-expert.md +109 -0
- package/skills/{alloy-expert → ti-expert}/references/code-conventions.md +182 -49
- package/skills/{alloy-expert → ti-expert}/references/controller-patterns.md +103 -93
- package/skills/{alloy-expert → ti-expert}/references/error-handling.md +12 -12
- package/skills/{alloy-expert → ti-expert}/references/examples.md +144 -85
- package/skills/{alloy-expert → ti-expert}/references/migration-patterns.md +38 -36
- package/skills/{alloy-expert → ti-expert}/references/patterns.md +8 -8
- package/skills/ti-expert/references/performance-listview.md +251 -0
- package/skills/{alloy-expert/references/performance-patterns.md → ti-expert/references/performance-optimization.md} +67 -283
- package/skills/{alloy-expert/references/security-patterns.md → ti-expert/references/security-device.md} +12 -295
- package/skills/ti-expert/references/security-fundamentals.md +284 -0
- package/skills/{alloy-expert → ti-expert}/references/state-management.md +10 -10
- package/skills/ti-expert/references/testing-e2e-ci.md +432 -0
- package/skills/ti-expert/references/testing-unit.md +433 -0
- package/skills/ti-expert/references/theming.md +394 -0
- package/skills/ti-guides/SKILL.md +1 -14
- package/skills/ti-guides/references/advanced-data-and-images.md +126 -10
- package/skills/ti-guides/references/app-distribution.md +48 -10
- package/skills/ti-guides/references/application-frameworks.md +9 -2
- package/skills/ti-guides/references/cli-reference.md +338 -82
- package/skills/ti-guides/references/coding-best-practices.md +14 -4
- package/skills/ti-guides/references/commonjs-advanced.md +103 -6
- package/skills/ti-guides/references/hello-world.md +5 -2
- package/skills/ti-guides/references/hyperloop-native-access.md +439 -46
- package/skills/ti-guides/references/javascript-primer.md +4 -3
- package/skills/ti-guides/references/resources.md +0 -1
- package/skills/ti-guides/references/style-and-conventions.md +57 -9
- package/skills/ti-guides/references/tiapp-config.md +48 -6
- package/skills/ti-howtos/SKILL.md +2 -27
- package/skills/ti-howtos/references/android-platform-deep-dives.md +41 -90
- package/skills/ti-howtos/references/automation-fastlane-appium.md +15 -14
- package/skills/ti-howtos/references/buffer-codec-streams.md +22 -22
- package/skills/ti-howtos/references/cross-platform-development.md +68 -37
- package/skills/ti-howtos/references/debugging-profiling.md +8 -53
- package/skills/ti-howtos/references/extending-titanium.md +12 -51
- package/skills/ti-howtos/references/google-maps-v2.md +30 -29
- package/skills/ti-howtos/references/ios-map-kit.md +19 -25
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +95 -283
- package/skills/ti-howtos/references/local-data-sources.md +45 -37
- package/skills/ti-howtos/references/location-and-maps.md +47 -28
- package/skills/ti-howtos/references/media-apis.md +84 -27
- package/skills/ti-howtos/references/notification-services.md +40 -89
- package/skills/ti-howtos/references/remote-data-sources.md +21 -36
- package/skills/ti-howtos/references/tutorials.md +79 -39
- package/skills/ti-howtos/references/using-modules.md +4 -30
- package/skills/ti-howtos/references/web-content-integration.md +28 -45
- package/skills/ti-howtos/references/webpack-build-pipeline.md +54 -18
- package/skills/ti-ui/SKILL.md +1 -21
- package/skills/ti-ui/references/accessibility-deep-dive.md +71 -25
- package/skills/ti-ui/references/animation-and-matrices.md +0 -47
- package/skills/ti-ui/references/application-structures.md +0 -46
- package/skills/ti-ui/references/custom-fonts-styling.md +9 -57
- package/skills/ti-ui/references/event-handling.md +32 -40
- package/skills/ti-ui/references/gestures.md +0 -40
- package/skills/ti-ui/references/icons-and-splash-screens.md +21 -44
- package/skills/ti-ui/references/layouts-and-positioning.md +47 -39
- package/skills/ti-ui/references/listviews-and-performance.md +187 -73
- package/skills/ti-ui/references/orientation.md +57 -71
- package/skills/ti-ui/references/platform-ui-android.md +114 -48
- package/skills/ti-ui/references/platform-ui-ios.md +63 -38
- package/skills/ti-ui/references/scrolling-views.md +14 -23
- package/skills/ti-ui/references/tableviews.md +6 -56
- package/lib/commands/install.js +0 -188
- package/skills/alloy-expert/references/anti-patterns.md +0 -133
- package/skills/alloy-expert/references/testing.md +0 -872
- package/skills/ti-guides/references/alloy-cli-advanced.md +0 -84
- package/skills/ti-guides/references/alloy-data-mastery.md +0 -29
- package/skills/ti-guides/references/alloy-widgets-and-themes.md +0 -19
- /package/skills/{alloy-expert → ti-expert}/assets/ControllerAutoCleanup.js +0 -0
- /package/skills/{alloy-expert → ti-expert}/references/contracts.md +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Alloy MVC
|
|
1
|
+
# Alloy MVC Structure Reference
|
|
2
2
|
|
|
3
3
|
## Standard Project Structure
|
|
4
4
|
|
|
@@ -10,34 +10,29 @@ app/
|
|
|
10
10
|
│ └── list.js # Controller for list view
|
|
11
11
|
├── models/ # OPTIONAL: For persistence with migrations
|
|
12
12
|
│ └── user.js # Model definition (ONLY if using SQLite)
|
|
13
|
-
├── views/ # XML views
|
|
13
|
+
├── views/ # XML views
|
|
14
14
|
│ ├── index.xml
|
|
15
15
|
│ └── feature/
|
|
16
|
-
│
|
|
16
|
+
│ └── list.xml # View definition
|
|
17
|
+
├── styles/ # TSS styles (one per view + global)
|
|
18
|
+
│ ├── app.tss # Global application styles
|
|
19
|
+
│ ├── index.tss # Styles for index view
|
|
20
|
+
│ └── feature/
|
|
21
|
+
│ └── list.tss # Styles for feature/list view
|
|
17
22
|
├── lib/ # Reusable logic (no UI)
|
|
18
23
|
│ ├── api/
|
|
19
24
|
│ │ └── client.js # API calls
|
|
20
25
|
│ ├── services/
|
|
21
26
|
│ │ ├── auth.js # Business logic services
|
|
22
27
|
│ │ ├── navigation.js # Navigation orchestration
|
|
23
|
-
│ │
|
|
24
|
-
│ │ └── purgetss.animation.js # PurgeTSS Animation module
|
|
28
|
+
│ │ └── nativeService.js # Native module wrapper (e.g. Audio, FB, Maps)
|
|
25
29
|
│ └── helpers/
|
|
26
30
|
│ ├── utils.js # Pure utility functions
|
|
27
31
|
│ └── i18n.js # Complex string transformations
|
|
28
32
|
├── widgets/ # Truly reusable components (used in 3+ places)
|
|
29
33
|
│ └── customButton/
|
|
30
|
-
├── styles/ # Global styles
|
|
31
|
-
│ ├── app.tss # GENERATED by PurgeTSS (Do not edit)
|
|
32
|
-
│ ├── _app.tss # YOUR custom styles (persists across runs)
|
|
33
|
-
│ └── fonts.tss # GENERATED by PurgeTSS build-fonts
|
|
34
34
|
├── config.json # Alloy configuration
|
|
35
35
|
└── alloy.js # Collections & Global services
|
|
36
|
-
|
|
37
|
-
./purgetss/
|
|
38
|
-
├── config.cjs # PurgeTSS theme configuration
|
|
39
|
-
└── styles/
|
|
40
|
-
└── utilities.tss # All utility classes
|
|
41
36
|
```
|
|
42
37
|
|
|
43
38
|
## lib/ Folder and Module Require Paths
|
|
@@ -145,14 +140,14 @@ api.getFrames()
|
|
|
145
140
|
## Controller Rules
|
|
146
141
|
|
|
147
142
|
**DO:**
|
|
148
|
-
-
|
|
143
|
+
- Define styles in TSS files (per-controller + `app.tss` for global).
|
|
149
144
|
- Orchestrate view and model/collection interactions.
|
|
150
145
|
- Handle UI events and delegate to services.
|
|
151
146
|
- Format data for display (simple cases).
|
|
152
147
|
- Manage view lifecycle (including cleanup).
|
|
153
148
|
|
|
154
149
|
**DON'T:**
|
|
155
|
-
-
|
|
150
|
+
- Use inline style attributes in XML (define in TSS files).
|
|
156
151
|
- Make direct API calls (use lib/api/ or lib/services/).
|
|
157
152
|
- Contain heavy business logic.
|
|
158
153
|
- Call native modules directly (use a service wrapper).
|
|
@@ -197,7 +192,7 @@ See [ControllerAutoCleanup.js](../assets/ControllerAutoCleanup.js) for the compl
|
|
|
197
192
|
- All static text must use `L('key')`.
|
|
198
193
|
- All interactive elements must have `accessibilityLabel`.
|
|
199
194
|
- Use `lib/helpers/i18n.js` for strings that require logic (e.g., "You have 5 messages").
|
|
200
|
-
- Use **
|
|
195
|
+
- Use **TSS platform modifiers** (`[platform=ios]`, `[platform=android]`) for platform-specific design instead of conditional code.
|
|
201
196
|
|
|
202
197
|
## Widget Structure
|
|
203
198
|
|
|
@@ -211,7 +206,7 @@ app/widgets/
|
|
|
211
206
|
├── views/
|
|
212
207
|
│ └── widget.xml # Main widget view
|
|
213
208
|
├── styles/
|
|
214
|
-
│ └── widget.tss # Widget-specific styles
|
|
209
|
+
│ └── widget.tss # Widget-specific styles
|
|
215
210
|
└── widget.json # Widget manifest
|
|
216
211
|
```
|
|
217
212
|
|
|
@@ -235,15 +230,23 @@ app/widgets/
|
|
|
235
230
|
### Widget View (widget.xml)
|
|
236
231
|
```xml
|
|
237
232
|
<Alloy>
|
|
238
|
-
<View id="container"
|
|
239
|
-
<View
|
|
240
|
-
<ActivityIndicator id="spinner"
|
|
241
|
-
<Label id="messageLabel"
|
|
233
|
+
<View id="container">
|
|
234
|
+
<View id="box">
|
|
235
|
+
<ActivityIndicator id="spinner" />
|
|
236
|
+
<Label id="messageLabel" />
|
|
242
237
|
</View>
|
|
243
238
|
</View>
|
|
244
239
|
</Alloy>
|
|
245
240
|
```
|
|
246
241
|
|
|
242
|
+
```tss
|
|
243
|
+
/* styles/widget.tss */
|
|
244
|
+
"#container": { width: Ti.UI.FILL, height: Ti.UI.FILL, visible: false, backgroundColor: 'rgba(0,0,0,0.5)' }
|
|
245
|
+
"#box": { width: 128, height: 128, layout: 'vertical', borderRadius: 16, backgroundColor: '#fff' }
|
|
246
|
+
"#spinner": { top: 24 }
|
|
247
|
+
"#messageLabel": { left: 16, right: 16, top: 16, font: { fontSize: 14 }, color: '#4b5563' }
|
|
248
|
+
```
|
|
249
|
+
|
|
247
250
|
### Widget Controller (widget.js)
|
|
248
251
|
```javascript
|
|
249
252
|
// Widget controller receives args via $.args
|
|
@@ -300,22 +303,126 @@ const loadData = () => {
|
|
|
300
303
|
}
|
|
301
304
|
```
|
|
302
305
|
|
|
303
|
-
:::tip
|
|
304
|
-
|
|
306
|
+
:::tip Widget Styles
|
|
307
|
+
Widgets have their own `styles/widget.tss` file. Define all widget-specific styles there to keep them self-contained and portable.
|
|
308
|
+
:::
|
|
309
|
+
|
|
310
|
+
### Widget ↔ Controller Communication
|
|
311
|
+
|
|
312
|
+
**Pattern 1: Public methods on $**
|
|
313
|
+
|
|
314
|
+
The widget exposes methods directly on `$`:
|
|
305
315
|
|
|
306
316
|
```javascript
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
317
|
+
// widgets/loadingOverlay/controllers/widget.js
|
|
318
|
+
$.show = (msg) => { /* ... */ }
|
|
319
|
+
$.hide = () => { /* ... */ }
|
|
320
|
+
|
|
321
|
+
// Parent controller
|
|
322
|
+
$.loader.show(L('loading'))
|
|
323
|
+
$.loader.hide()
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Pattern 2: Callbacks via $.args**
|
|
327
|
+
|
|
328
|
+
Pass functions as arguments for child → parent communication:
|
|
329
|
+
|
|
330
|
+
```xml
|
|
331
|
+
<!-- Parent view -->
|
|
332
|
+
<Widget id="picker" src="datePicker" />
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
```javascript
|
|
336
|
+
// Parent controller - pass callback after creation
|
|
337
|
+
$.picker.onDateSelected = (date) => {
|
|
338
|
+
$.dateLabel.text = formatDate(date)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Widget controller
|
|
342
|
+
function handleSelection(e) {
|
|
343
|
+
if ($.args.onDateSelected) {
|
|
344
|
+
$.args.onDateSelected(e.value)
|
|
345
|
+
}
|
|
346
|
+
// Or if set as property:
|
|
347
|
+
if ($._onDateSelected) {
|
|
348
|
+
$._onDateSelected(e.value)
|
|
313
349
|
}
|
|
314
350
|
}
|
|
315
351
|
```
|
|
316
352
|
|
|
317
|
-
|
|
318
|
-
|
|
353
|
+
**Pattern 3: Backbone Events (for complex communication)**
|
|
354
|
+
|
|
355
|
+
```javascript
|
|
356
|
+
// Widget controller (emits events)
|
|
357
|
+
$.trigger('item:selected', { item: selectedItem })
|
|
358
|
+
$.trigger('search:changed', { query: text })
|
|
359
|
+
|
|
360
|
+
// Parent controller (listens)
|
|
361
|
+
$.searchWidget.on('search:changed', (data) => {
|
|
362
|
+
filterResults(data.query)
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
// Cleanup in parent
|
|
366
|
+
function cleanup() {
|
|
367
|
+
$.searchWidget.off('search:changed')
|
|
368
|
+
$.destroy()
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Widget with Internal State
|
|
373
|
+
|
|
374
|
+
```javascript
|
|
375
|
+
// widgets/counter/controllers/widget.js
|
|
376
|
+
let count = parseInt($.args.initial || '0', 10)
|
|
377
|
+
|
|
378
|
+
function render() {
|
|
379
|
+
$.countLabel.text = String(count)
|
|
380
|
+
$.decrementBtn.enabled = count > 0
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
$.increment = () => {
|
|
384
|
+
count++
|
|
385
|
+
render()
|
|
386
|
+
$.trigger('change', { value: count })
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
$.decrement = () => {
|
|
390
|
+
if (count > 0) {
|
|
391
|
+
count--
|
|
392
|
+
render()
|
|
393
|
+
$.trigger('change', { value: count })
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
$.getValue = () => count
|
|
398
|
+
|
|
399
|
+
$.setValue = (val) => {
|
|
400
|
+
count = val
|
|
401
|
+
render()
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Expose for click handlers in XML
|
|
405
|
+
$.incrementBtn.addEventListener('click', $.increment)
|
|
406
|
+
$.decrementBtn.addEventListener('click', $.decrement)
|
|
407
|
+
|
|
408
|
+
$.cleanup = () => {
|
|
409
|
+
$.incrementBtn.removeEventListener('click', $.increment)
|
|
410
|
+
$.decrementBtn.removeEventListener('click', $.decrement)
|
|
411
|
+
$.destroy()
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
render()
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### When to Use Widget vs Require
|
|
418
|
+
|
|
419
|
+
| Use `<Widget>` when | Use `<Require>` when |
|
|
420
|
+
| ------------------------------------- | ------------------------------- |
|
|
421
|
+
| Component is used in 3+ places | Component is used in 1-2 places |
|
|
422
|
+
| Needs its own self-contained styles | Shares styles with parent |
|
|
423
|
+
| Has public API (show/hide/setValue) | Just renders, no API needed |
|
|
424
|
+
| Could be extracted to another project | Specific to this app |
|
|
425
|
+
| Needs its own `widget.json` manifest | Lightweight, no manifest needed |
|
|
319
426
|
|
|
320
427
|
## config.json Reference
|
|
321
428
|
|
|
@@ -371,11 +478,11 @@ if (Alloy.CFG.debug) {
|
|
|
371
478
|
|
|
372
479
|
### Key Configuration Options
|
|
373
480
|
|
|
374
|
-
| Property | Description
|
|
375
|
-
| -------------- |
|
|
376
|
-
| `theme` | Theme folder to use from `app/themes/`
|
|
377
|
-
| `autoStyle` | Auto-apply TSS styles
|
|
378
|
-
| `backbone` | Backbone.js version to use
|
|
379
|
-
| `sourcemap` | Generate source maps for debugging
|
|
380
|
-
| `dependencies` | Widget dependencies and versions
|
|
381
|
-
| `adaptersPath` | Custom path for sync adapters
|
|
481
|
+
| Property | Description |
|
|
482
|
+
| -------------- | ----------------------------------------- |
|
|
483
|
+
| `theme` | Theme folder to use from `app/themes/` |
|
|
484
|
+
| `autoStyle` | Auto-apply TSS styles by element ID/class |
|
|
485
|
+
| `backbone` | Backbone.js version to use |
|
|
486
|
+
| `sourcemap` | Generate source maps for debugging |
|
|
487
|
+
| `dependencies` | Widget dependencies and versions |
|
|
488
|
+
| `adaptersPath` | Custom path for sync adapters |
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Titanium Alloy Anti-Patterns
|
|
2
|
+
|
|
3
|
+
## 1. Inline Styling Instead of TSS
|
|
4
|
+
**Symptom:** Using inline attributes like `backgroundColor="#fff"` directly in XML views.
|
|
5
|
+
**Problem:** Inline attributes make theme changes impossible and scatter visual definitions across views.
|
|
6
|
+
**Solution:** Define styles in TSS files using IDs or class selectors.
|
|
7
|
+
|
|
8
|
+
## 2. Fat Controllers
|
|
9
|
+
**Symptom:** Controllers with 100+ lines handling logic, API, and UI.
|
|
10
|
+
**Solution:** Delegate business logic to `lib/services/` and API calls to `lib/api/`.
|
|
11
|
+
|
|
12
|
+
## 3. Memory Leaks (Missing Cleanup)
|
|
13
|
+
**Symptom:** Adding `Ti.App` or `Alloy.Collections` listeners without a `cleanup()` function.
|
|
14
|
+
**Solution:** Always implement `$.cleanup = cleanup` and remove listeners there.
|
|
15
|
+
|
|
16
|
+
## 4. Direct Native Module Calls
|
|
17
|
+
**Symptom:** Calling `require('ti.module')` directly in a controller.
|
|
18
|
+
**Solution:** Wrap it in a service in `lib/services/` (e.g., `audioService.js`).
|
|
19
|
+
|
|
20
|
+
## 5. Direct Controller Navigation
|
|
21
|
+
**Symptom:** `Alloy.createController('name').getView().open()`.
|
|
22
|
+
**Solution:** Use a Navigation Service to centralize `open/close` and trigger the `cleanup()` function automatically.
|
|
23
|
+
|
|
24
|
+
## 6. Complex Matrix Animations
|
|
25
|
+
**Symptom:** Manual use of `Ti.UI.create2DMatrix()` for simple animations.
|
|
26
|
+
**Solution:** Use `Ti.UI.createAnimation()` for opacity, transform, and duration-based animations. Reserve 2D Matrix for complex multi-property transforms.
|
|
27
|
+
|
|
28
|
+
## 7. Hardcoded Strings & Missing a11y
|
|
29
|
+
**Symptom:** `text="Login"` instead of `text="L('login')"`, or missing `accessibilityLabel`.
|
|
30
|
+
**Solution:** Always use i18n and accessibility properties.
|
|
31
|
+
|
|
32
|
+
## 8. Logic in TSS
|
|
33
|
+
**Symptom:** Using conditionals or calculations inside TSS.
|
|
34
|
+
**Solution:** Keep styling declarative in TSS files.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Titanium Layout Anti-Patterns
|
|
39
|
+
|
|
40
|
+
## 9. Padding on Container Views
|
|
41
|
+
**Symptom:** Setting `padding` on View, Window, ScrollView, or TableView.
|
|
42
|
+
**Problem:** Base container elements don't support padding in Titanium.
|
|
43
|
+
**Solution:** Use margins on children instead:
|
|
44
|
+
```tss
|
|
45
|
+
/* WRONG */
|
|
46
|
+
"#container": { padding: 16 }
|
|
47
|
+
|
|
48
|
+
/* CORRECT - margin on children */
|
|
49
|
+
"#childLabel": { left: 16, top: 16, right: 16 }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 10. Redundant Composite Layout
|
|
53
|
+
**Symptom:** Adding `layout: 'composite'` to Views.
|
|
54
|
+
**Problem:** Composite (absolute positioning) is the DEFAULT layout. Setting it is redundant.
|
|
55
|
+
**Solution:** Omit `layout` for composite, only specify `layout: 'horizontal'` or `layout: 'vertical'` when needed.
|
|
56
|
+
|
|
57
|
+
## 11. Using `lib/` Prefix in Require Statements
|
|
58
|
+
**Symptom:** `const service = require('lib/services/picsum')`
|
|
59
|
+
**Problem:** Alloy flattens the `lib/` folder during build. Files in `app/lib/services/` become `Resources/iphone/services/`.
|
|
60
|
+
**Solution:** Omit the `lib/` prefix: `const service = require('services/picsum')`
|
|
61
|
+
|
|
62
|
+
## 12. Wrong Window ID in Controller
|
|
63
|
+
**Symptom:** Using `$.index.open()` when the Window has `id="mainWindow"`.
|
|
64
|
+
**Problem:** Alloy generates `$` references from XML IDs. If Window is `id="mainWindow"`, `$.index` doesn't exist.
|
|
65
|
+
**Solution:** Match the ID: `$.mainWindow.open()`
|
|
66
|
+
|
|
67
|
+
## 13. Using `Ti.UI.createNotification`
|
|
68
|
+
**Symptom:** `Ti.UI.createNotification({ message: 'Hi' }).show()`
|
|
69
|
+
**Problem:** This API doesn't exist in Titanium. Causes "invalid method" error.
|
|
70
|
+
**Solution:** Use `Ti.UI.createAlertDialog` for simple messages, or create custom toast views.
|
|
71
|
+
|
|
72
|
+
## 14. Using Nonexistent iOS Share APIs
|
|
73
|
+
**Symptom:** `Ti.UI.iOS.createActivityPopover` or `alloy/social` with wrong methods.
|
|
74
|
+
**Problem:** These APIs either don't exist or have changed. Causes runtime errors.
|
|
75
|
+
**Solution:**
|
|
76
|
+
- iOS: Use `Ti.UI.iOS.createDocumentViewer` for files, or simple `Ti.UI.createOptionDialog` + `Ti.UI.Clipboard` for links
|
|
77
|
+
- Android: Use `Ti.Android.createIntent` with ACTION_SEND
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Quick Reference Table
|
|
82
|
+
|
|
83
|
+
| Anti-Pattern | Why It Fails | Correct Approach |
|
|
84
|
+
| ----------------------- | ------------------------ | --------------------- |
|
|
85
|
+
| `padding` on View | No padding on containers | Margins on children |
|
|
86
|
+
| `layout: 'composite'` | Already default | Omit it |
|
|
87
|
+
| Inline style attributes | Scattered styling | Define in TSS files |
|
|
88
|
+
| `lib/` prefix | lib/ is flattened | Use path without lib/ |
|
|
89
|
+
| `$.index.open()` | Wrong ID reference | Use actual Window ID |
|
|
90
|
+
| `createNotification` | API doesn't exist | `createAlertDialog` |
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# CLI Expert Strategies & TiNy
|
|
2
|
+
|
|
3
|
+
Mastering the command line is essential for a Titanium expert. This guide covers advanced workflows, optimization techniques, and the use of **TiNy (`tn`)** for efficient development.
|
|
4
|
+
|
|
5
|
+
## The Expert Workflow
|
|
6
|
+
|
|
7
|
+
An expert doesn't just run `ti build`. They optimize for speed, reliability, and automation.
|
|
8
|
+
|
|
9
|
+
### 1. The "Inner Loop" Optimization
|
|
10
|
+
Reduce the time between writing code and seeing it on the device.
|
|
11
|
+
|
|
12
|
+
- **LiveView**: Use `--liveview` for near-instant UI updates without full recompilation.
|
|
13
|
+
```bash
|
|
14
|
+
ti build -p ios --liveview
|
|
15
|
+
```
|
|
16
|
+
- **Build Only**: Use `-b` to verify Alloy compilation and JavaScript syntax without launching the simulator.
|
|
17
|
+
```bash
|
|
18
|
+
ti build -p ios -b
|
|
19
|
+
```
|
|
20
|
+
- **Skip Minification**: In development, always skip minification to speed up the build process.
|
|
21
|
+
```bash
|
|
22
|
+
ti build -p ios --skip-js-minify
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### 2. Precise Cleaning
|
|
26
|
+
Don't use `ti clean` as a first resort (it's slow).
|
|
27
|
+
- **Targeted Clean**: If Alloy isn't reflecting changes, try deleting `Resources/` and `build/` manually or use `ti clean -p <platform>`.
|
|
28
|
+
- **Pre-Production**: Always run a full `ti clean` before a production/App Store build to ensure no stale assets are included.
|
|
29
|
+
|
|
30
|
+
### 3. Advanced Debugging
|
|
31
|
+
- **Trace Logging**: Use `--log-level trace` when a build fails for mysterious reasons (e.g., a broken hook or native module issue).
|
|
32
|
+
- **Build Logs**: Check `build/build.log` for the full output of the last build process.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## TiNy (`tn`): The Expert's Power Tool
|
|
37
|
+
|
|
38
|
+
**TiNy** is a modern CLI wrapper for Titanium SDK that drastically reduces keystrokes and manages complex build configurations through "recipes".
|
|
39
|
+
|
|
40
|
+
### Why Experts Use TiNy
|
|
41
|
+
- **Speed**: `tn ios` vs `ti build -p ios -T simulator`.
|
|
42
|
+
- **Consistency**: Recipes ensure every team member builds with the same flags.
|
|
43
|
+
- **Device Management**: Easily target specific simulators/emulators by name.
|
|
44
|
+
|
|
45
|
+
### Quick Start
|
|
46
|
+
1. **Install**: `npm install -g tn`
|
|
47
|
+
2. **Repo**: https://github.com/jasonkneen/tn
|
|
48
|
+
3. **Generate Recipes**: Detect all connected devices/simulators.
|
|
49
|
+
```bash
|
|
50
|
+
tn generate
|
|
51
|
+
```
|
|
52
|
+
4. **Build**:
|
|
53
|
+
```bash
|
|
54
|
+
tn iphone-16-pro
|
|
55
|
+
tn pixel-8-pro-api-34
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Expert Recipes
|
|
59
|
+
Recipes can be flags or options. Multiple recipes can be combined.
|
|
60
|
+
|
|
61
|
+
| Command | Expansion |
|
|
62
|
+
| -------------- | ----------------------------------- |
|
|
63
|
+
| `tn ios` | `--platform ios` |
|
|
64
|
+
| `tn android` | `--platform android` |
|
|
65
|
+
| `tn appstore` | `--ios --target dist-appstore` |
|
|
66
|
+
| `tn playstore` | `--android --target dist-playstore` |
|
|
67
|
+
| `tn watch` | `--ios --launch-watch-app` |
|
|
68
|
+
|
|
69
|
+
### Customizing Your Workflow
|
|
70
|
+
- **Save Global Recipe**:
|
|
71
|
+
```bash
|
|
72
|
+
tn save my-debug --ios --simulator --log-level trace --skip-js-minify
|
|
73
|
+
```
|
|
74
|
+
- **Project-Specific Recipes**: Save a `tn.json` in your project root for team-wide recipes (e.g., specific provisioning profiles).
|
|
75
|
+
```bash
|
|
76
|
+
tn project save release --playstore --keystore ./android/release.keystore
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Composition & Placeholders
|
|
80
|
+
You can use `%s` as a placeholder in recipes for values:
|
|
81
|
+
```bash
|
|
82
|
+
tn save ci -b --pp-uuid <UUID> --distribution-name "<NAME>" --ah --installr --installr-release-notes %s
|
|
83
|
+
|
|
84
|
+
# Usage:
|
|
85
|
+
tn ci "Fixed login bug"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Automation Integration
|
|
91
|
+
|
|
92
|
+
Experts automate their builds using `package.json` scripts, often combining `ti` or `tn` with other tools.
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
"scripts": {
|
|
96
|
+
"start": "tn ios --liveview",
|
|
97
|
+
"build:android": "tn android",
|
|
98
|
+
"clean": "ti clean",
|
|
99
|
+
"prod:ios": "tn appstore --distribution-name 'My Company'",
|
|
100
|
+
"lint": "eslint app/"
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Pro-Tips
|
|
107
|
+
- **SDK Switching**: Use `-s <version>` to test your app against a specific SDK version without changing your global default.
|
|
108
|
+
- **Sim Focus**: Use `--no-sim-focus` if you want to keep your editor in focus while the simulator launches in the background.
|
|
109
|
+
- **Concurrent Builds**: You can often build for iOS and Android simultaneously in different terminal tabs if your machine has the resources.
|