@maccesar/titools 3.2.0 → 4.0.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.
Files changed (102) hide show
  1. package/README.md +27 -61
  2. package/lib/cleanup.js +29 -0
  3. package/lib/commands/agents.js +8 -7
  4. package/lib/commands/skills.js +118 -23
  5. package/lib/config.js +13 -15
  6. package/lib/installer.js +5 -3
  7. package/lib/utils.js +36 -0
  8. package/package.json +1 -1
  9. package/skills/alloy-guides/SKILL.md +188 -0
  10. package/skills/alloy-guides/references/CLI_TASKS.md +233 -0
  11. package/skills/alloy-guides/references/CONCEPTS.md +171 -0
  12. package/skills/alloy-guides/references/CONTROLLERS.md +279 -0
  13. package/skills/alloy-guides/references/MODELS.md +742 -0
  14. package/skills/alloy-guides/references/MODELS_ADVANCED.md +482 -0
  15. package/skills/alloy-guides/references/PURGETSS.md +57 -0
  16. package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +235 -0
  17. package/skills/alloy-guides/references/VIEWS_STYLES.md +375 -0
  18. package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +102 -0
  19. package/skills/alloy-guides/references/VIEWS_XML.md +581 -0
  20. package/skills/alloy-guides/references/WIDGETS.md +160 -0
  21. package/skills/alloy-howtos/SKILL.md +179 -0
  22. package/skills/alloy-howtos/references/best_practices.md +121 -0
  23. package/skills/alloy-howtos/references/cli_reference.md +230 -0
  24. package/skills/alloy-howtos/references/config_files.md +158 -0
  25. package/skills/alloy-howtos/references/custom_tags.md +148 -0
  26. package/skills/alloy-howtos/references/debugging_troubleshooting.md +78 -0
  27. package/skills/alloy-howtos/references/samples.md +156 -0
  28. package/skills/purgetss/SKILL.md +184 -181
  29. package/skills/purgetss/references/EXAMPLES.md +8 -6
  30. package/skills/purgetss/references/app-branding.md +5 -0
  31. package/skills/purgetss/references/apply-directive.md +1 -1
  32. package/skills/purgetss/references/class-categories.md +1 -1
  33. package/skills/purgetss/references/class-index-properties.md +618 -0
  34. package/skills/purgetss/references/class-index.md +4 -610
  35. package/skills/purgetss/references/cli-commands.md +41 -410
  36. package/skills/purgetss/references/custom-fonts.md +292 -0
  37. package/skills/purgetss/references/custom-rules.md +1 -1
  38. package/skills/purgetss/references/customization-deep-dive.md +64 -1
  39. package/skills/purgetss/references/icon-fonts.md +208 -118
  40. package/skills/purgetss/references/installation-setup.md +4 -4
  41. package/skills/purgetss/references/migration-guide.md +53 -1
  42. package/skills/purgetss/references/multi-density-images.md +53 -2
  43. package/skills/purgetss/references/svg-pipeline.md +249 -0
  44. package/skills/purgetss/references/tikit-components.md +2 -2
  45. package/skills/purgetss/references/titanium-resets.md +2 -2
  46. package/skills/purgetss/references/ui-ux-design.md +7 -5
  47. package/skills/purgetss/references/version-history.md +71 -82
  48. package/skills/ti-api/SKILL.md +128 -0
  49. package/skills/ti-api/references/api-android.md +675 -0
  50. package/skills/ti-api/references/api-app-platform.md +636 -0
  51. package/skills/ti-api/references/api-core.md +764 -0
  52. package/skills/ti-api/references/api-data-network.md +641 -0
  53. package/skills/ti-api/references/api-media.md +655 -0
  54. package/skills/ti-api/references/api-modules-ble-bluetooth.md +657 -0
  55. package/skills/ti-api/references/api-modules-coremotion-urlsession.md +411 -0
  56. package/skills/ti-api/references/api-modules-map.md +632 -0
  57. package/skills/ti-api/references/api-modules-nfc.md +725 -0
  58. package/skills/ti-api/references/api-modules-social-misc.md +526 -0
  59. package/skills/ti-api/references/api-services.md +700 -0
  60. package/skills/ti-api/references/api-ui-android.md +499 -0
  61. package/skills/ti-api/references/api-ui-extras.md +702 -0
  62. package/skills/ti-api/references/api-ui-ios-animator.md +378 -0
  63. package/skills/ti-api/references/api-ui-ios.md +756 -0
  64. package/skills/ti-api/references/api-ui-lists.md +581 -0
  65. package/skills/ti-api/references/api-ui-text-input.md +607 -0
  66. package/skills/ti-api/references/api-ui-views.md +572 -0
  67. package/skills/ti-api/references/api-ui-windows-navigation.md +676 -0
  68. package/skills/ti-api/references/api-xml-global.md +743 -0
  69. package/skills/ti-guides/SKILL.md +82 -0
  70. package/skills/ti-guides/references/advanced-data-and-images.md +155 -0
  71. package/skills/ti-guides/references/android-manifest.md +97 -0
  72. package/skills/ti-guides/references/app-distribution.md +373 -0
  73. package/skills/ti-guides/references/application-frameworks.md +366 -0
  74. package/skills/ti-guides/references/cli-reference.md +700 -0
  75. package/skills/ti-guides/references/coding-best-practices.md +150 -0
  76. package/skills/ti-guides/references/commonjs-advanced.md +279 -0
  77. package/skills/ti-guides/references/hello-world.md +99 -0
  78. package/skills/ti-guides/references/hyperloop-native-access.md +458 -0
  79. package/skills/ti-guides/references/javascript-primer.md +402 -0
  80. package/skills/ti-guides/references/reserved-words.md +36 -0
  81. package/skills/ti-guides/references/resources.md +172 -0
  82. package/skills/ti-guides/references/style-and-conventions.md +104 -0
  83. package/skills/ti-guides/references/tiapp-config.md +655 -0
  84. package/skills/ti-howtos/SKILL.md +131 -0
  85. package/skills/ti-howtos/references/android-platform-deep-dives.md +609 -0
  86. package/skills/ti-howtos/references/automation-fastlane-appium.md +96 -0
  87. package/skills/ti-howtos/references/buffer-codec-streams.md +162 -0
  88. package/skills/ti-howtos/references/cross-platform-development.md +358 -0
  89. package/skills/ti-howtos/references/debugging-profiling.md +473 -0
  90. package/skills/ti-howtos/references/extending-titanium.md +684 -0
  91. package/skills/ti-howtos/references/google-maps-v2.md +172 -0
  92. package/skills/ti-howtos/references/ios-map-kit.md +149 -0
  93. package/skills/ti-howtos/references/ios-platform-deep-dives.md +595 -0
  94. package/skills/ti-howtos/references/local-data-sources.md +310 -0
  95. package/skills/ti-howtos/references/location-and-maps.md +267 -0
  96. package/skills/ti-howtos/references/media-apis.md +268 -0
  97. package/skills/ti-howtos/references/notification-services.md +539 -0
  98. package/skills/ti-howtos/references/remote-data-sources.md +339 -0
  99. package/skills/ti-howtos/references/tutorials.md +552 -0
  100. package/skills/ti-howtos/references/using-modules.md +182 -0
  101. package/skills/ti-howtos/references/web-content-integration.md +288 -0
  102. package/skills/ti-howtos/references/webpack-build-pipeline.md +125 -0
@@ -0,0 +1,162 @@
1
+ # Buffer, Codec, and streams
2
+
3
+ Guide to binary data manipulation and data flows in Titanium SDK.
4
+
5
+ ## 1. Titanium.Buffer
6
+
7
+ Buffers are mutable, resizable containers for bytes (byte arrays).
8
+
9
+ ### Creating buffers
10
+ ```javascript
11
+ // Empty buffer (initial length 0)
12
+ const buffer0 = Ti.createBuffer();
13
+
14
+ // Empty 512-byte buffer
15
+ const buffer1 = Ti.createBuffer({ length: 512 });
16
+
17
+ // Buffer initialized with a string (UTF-8 by default)
18
+ const buffer2 = Ti.createBuffer({ value: 'Hello World' });
19
+
20
+ // Buffer initialized with explicit charset
21
+ const buffer3 = Ti.createBuffer({ value: 'Hello World', type: Ti.Codec.CHARSET_UTF16 });
22
+ ```
23
+
24
+ ### Common operations
25
+ ```javascript
26
+ const b1 = Ti.createBuffer({ value: 'Part 1. ' });
27
+ const b2 = Ti.createBuffer({ value: 'Part 2.' });
28
+
29
+ // Append (resizes b1)
30
+ b1.append(b2);
31
+
32
+ // Insert at position (resizes buffer as needed)
33
+ const extra = Ti.createBuffer({ value: 'X' });
34
+ b1.insert(extra, 1); // insert extra at index 1
35
+
36
+ // Truncate
37
+ b1.length = 10;
38
+
39
+ // Direct array access — buffer is NOT auto-extended; values must be byte values
40
+ b1[0] = 72; // 'H' (ASCII). b1[100] = 1 would throw if index >= b1.length
41
+
42
+ // Free memory
43
+ b1.release();
44
+ ```
45
+
46
+ ## 2. Titanium.Codec
47
+
48
+ The Codec module encodes and decodes primitive data (numbers and strings) to and from buffers.
49
+
50
+ ### Encoding numbers
51
+ ```javascript
52
+ const buffer = Ti.createBuffer({ length: 8 });
53
+ Ti.Codec.encodeNumber({
54
+ source: 12345,
55
+ dest: buffer,
56
+ type: Ti.Codec.TYPE_INT,
57
+ byteOrder: Ti.Codec.BIG_ENDIAN
58
+ });
59
+ ```
60
+
61
+ ### Encoding strings
62
+ ```javascript
63
+ // Encode a string into a buffer; returns the byte length written
64
+ const buffer = Ti.createBuffer({ length: 1024 });
65
+ const encodedLength = Ti.Codec.encodeString({
66
+ source: 'hello world',
67
+ dest: buffer
68
+ });
69
+ // Trim buffer to actual content
70
+ buffer.length = encodedLength;
71
+ ```
72
+
73
+ ### Decoding strings
74
+ ```javascript
75
+ const text = Ti.Codec.decodeString({
76
+ source: buffer,
77
+ charset: Ti.Codec.CHARSET_UTF8
78
+ });
79
+ ```
80
+
81
+ ### Supported types and charsets
82
+
83
+ Numeric types: `TYPE_BYTE`, `TYPE_SHORT`, `TYPE_INT`, `TYPE_LONG`, `TYPE_FLOAT`, `TYPE_DOUBLE`
84
+
85
+ String charsets: `CHARSET_UTF8`, `CHARSET_UTF16`, `CHARSET_UTF16BE`, `CHARSET_UTF16LE`, `CHARSET_ISO_LATIN1`
86
+
87
+ ### Position parameter
88
+ The `position` parameter controls where encoding or decoding starts in the buffer:
89
+ ```javascript
90
+ Ti.Codec.encodeNumber({
91
+ source: 42,
92
+ dest: buffer,
93
+ position: 4, // start writing at byte 4
94
+ type: Ti.Codec.TYPE_INT
95
+ });
96
+ ```
97
+
98
+ ## 3. Streams
99
+
100
+ Streams let you read and write data in a serialized, memory-efficient way.
101
+
102
+ ### Stream types
103
+ 1. BufferStream: for reading and writing in-memory buffers
104
+ 2. FileStream: for file operations (more efficient than `file.read()`)
105
+ 3. BlobStream: read-only for Blob objects (images, camera)
106
+
107
+ Stream modes: `Ti.Filesystem.MODE_READ`, `Ti.Filesystem.MODE_WRITE`, `Ti.Filesystem.MODE_APPEND`
108
+
109
+ ### Example: BufferStream
110
+ ```javascript
111
+ const buffer = Ti.createBuffer({ length: 1024 });
112
+ const stream = Ti.Stream.createStream({
113
+ source: buffer,
114
+ mode: Ti.Stream.MODE_WRITE
115
+ });
116
+
117
+ stream.write(Ti.createBuffer({ value: 'Stream data' }));
118
+ stream.close();
119
+ ```
120
+
121
+ ### Example: FileStream (chunk-based reading)
122
+ ```javascript
123
+ const file = Ti.Filesystem.getFile('large_file.txt');
124
+ const instream = file.open(Ti.Filesystem.MODE_READ);
125
+ const buffer = Ti.createBuffer({ length: 1024 }); // 1KB chunks
126
+
127
+ let bytesRead = 0;
128
+ while ((bytesRead = instream.read(buffer)) > 0) {
129
+ Ti.API.info(`Read ${bytesRead} bytes`);
130
+ // Process buffer...
131
+ }
132
+ instream.close();
133
+ ```
134
+
135
+ ### Example: BlobStream (camera to file)
136
+ ```javascript
137
+ Ti.Media.showCamera({
138
+ success: (e) => {
139
+ const instream = Ti.Stream.createStream({
140
+ source: e.media,
141
+ mode: Ti.Stream.MODE_READ
142
+ });
143
+
144
+ const outfile = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'photo.jpg');
145
+ const outstream = outfile.open(Ti.Filesystem.MODE_WRITE);
146
+
147
+ const buffer = Ti.createBuffer({ length: 4096 });
148
+ let readBytes = 0;
149
+ while ((readBytes = instream.read(buffer)) > 0) {
150
+ outstream.write(buffer, 0, readBytes);
151
+ }
152
+
153
+ instream.close();
154
+ outstream.close();
155
+ }
156
+ });
157
+ ```
158
+
159
+ ## 4. Best practices
160
+ - Always close streams to avoid memory leaks and file locks.
161
+ - Use chunks for large files or networking (for example, 1KB or 4KB) to avoid saturating RAM.
162
+ - Buffers vs Blobs: Buffers are mutable; Blobs are immutable. Convert a Blob to a Buffer if you need to modify bytes.
@@ -0,0 +1,358 @@
1
+ # Cross-platform development
2
+
3
+ Strategies for building Titanium apps that run on iOS and Android from a single codebase.
4
+
5
+ ## Philosophy
6
+
7
+ ### "Write once, adapt everywhere"
8
+ Titanium is not "write once, run anywhere." It is "write once, adapt everywhere."
9
+
10
+ Shared (90-100%):
11
+ - Business logic
12
+ - Networking code
13
+ - Database operations
14
+ - Event handling
15
+ - Data models
16
+
17
+ Different:
18
+ - UI conventions (tab position, navigation)
19
+ - Platform-specific features
20
+ - Hardware capabilities
21
+ - User expectations
22
+
23
+ ### Embrace the platform
24
+ Good apps feel native on each platform:
25
+
26
+ - iOS: bottom tabs, left navigation buttons, iOS-specific controls
27
+ - Android: top tabs, Menu button (legacy), Action Bar, Material Design
28
+
29
+ Develop for both platforms from day one. It is much easier than porting later.
30
+
31
+ ### Android platform key concepts
32
+ - Screen sizes: small, normal, large, xlarge (measured in dp). Use density-independent resources.
33
+ - Screen densities: ldpi (~120 dpi), mdpi (~160 dpi), hdpi (~240 dpi), xhdpi (~320 dpi), xxhdpi (~480 dpi), xxxhdpi (~640 dpi)
34
+ - Activities: each heavyweight Window maps to an Android Activity. Titanium manages the Activity lifecycle.
35
+ - Intents: for inter-app and intra-app communication. See `android-platform-deep-dives.md`.
36
+ - Back button: hardware/software back closes the current Window by default. Override with `window.addEventListener('androidback', ...)`.
37
+
38
+ ### iOS platform key concepts
39
+ - Human Interface Guidelines: Apple enforces design standards through App Store review. Follow iOS conventions for navigation, tab bars, and gestures.
40
+ - One-button design: no hardware back or menu buttons. All navigation must be in the UI (NavigationWindow, back buttons).
41
+ - Frameworks: Titanium wraps UIKit, Foundation, MapKit, and other Cocoa Touch frameworks. Use Hyperloop for additional frameworks.
42
+ - Developer account: requires a paid Apple Developer Program membership for device testing and App Store distribution.
43
+
44
+ ## Platform identification
45
+
46
+ ### Platform properties
47
+
48
+ ```javascript
49
+ // Platform name
50
+ Ti.Platform.name // "iPhone OS", "android", "mobileweb"
51
+ Ti.Platform.osname // "iphone", "ipad", "android", "mobileweb"
52
+ Ti.Platform.model // "iPhone 15", "Pixel 8", etc.
53
+ ```
54
+
55
+ ### Best practice: cache platform checks
56
+
57
+ ```javascript
58
+ // Create aliases - query once, use many times
59
+ const osname = Ti.Platform.osname;
60
+ const isAndroid = (osname === 'android');
61
+ const isIOS = (osname === 'iphone' || osname === 'ipad');
62
+ const isMobileWeb = (osname === 'mobileweb');
63
+ ```
64
+
65
+ ### Anti-pattern: do not assume binary
66
+
67
+ ```javascript
68
+ // BAD: Assumes if not Android, then iOS
69
+ if (osname !== 'android') {
70
+ // Wrong! Could be mobile web or future platform
71
+ }
72
+
73
+ // GOOD: Explicit checks
74
+ if (isAndroid) {
75
+ // Android code
76
+ } else if (isIOS) {
77
+ // iOS code
78
+ }
79
+ ```
80
+
81
+ ## Coding strategies
82
+
83
+ ### 1. Branching (mostly similar code)
84
+ Use when code is 90%+ the same with small differences.
85
+
86
+ ```javascript
87
+ const isAndroid = (Ti.Platform.osname === 'android');
88
+
89
+ const win = Ti.UI.createWindow({
90
+ backgroundColor: 'white',
91
+ // Platform-specific property
92
+ softInputMode: isAndroid ? Ti.UI.Android.SOFT_INPUT_ADJUST_PAN : null
93
+ });
94
+ ```
95
+
96
+ Tips:
97
+ - Cache platform checks to avoid repeated bridge crossings
98
+ - Group as much code as possible within branches
99
+ - Defer loading to reduce performance impact
100
+
101
+ ### 2. Platform-specific files (mostly different code)
102
+ Use when code differs significantly between platforms.
103
+
104
+ Structure:
105
+ ```
106
+ Resources/
107
+ ├── ui.js // Common code (optional)
108
+ ├── android/
109
+ │ └── ui.js // Android-specific (overrides)
110
+ └── iphone/
111
+ └── ui.js // iOS-specific (overrides)
112
+ ```
113
+
114
+ Usage:
115
+ ```javascript
116
+ // Will automatically include the specific version
117
+ const ui = require('ui');
118
+ // Loads: /android/ui.js on Android, /iphone/ui.js on iOS
119
+ ```
120
+
121
+ ### 3. Execution contexts
122
+ Titanium supports single-context and multi-context apps:
123
+
124
+ - Single context (recommended): all windows share one JavaScript runtime. Use `require()` for modules and `Alloy.createController()` for views.
125
+ - Multi-context (legacy): `Ti.UI.createWindow({ url: 'other.js' })` creates a separate JavaScript context. Variables are not shared between contexts.
126
+
127
+ Avoid multi-context apps. Use CommonJS modules and `require()` instead. If you must communicate across contexts, use `Ti.App.fireEvent()` and `Ti.App.addEventListener()`.
128
+
129
+ Avoid multiple contexts:
130
+ ```javascript
131
+ // Creates a new context - variables from app.js are not available
132
+ Ti.UI.createWindow({
133
+ url: 'window.js' // DO NOT DO THIS
134
+ }).open();
135
+ ```
136
+
137
+ Use instead:
138
+ ```javascript
139
+ // Same context - all variables available
140
+ const win = Ti.UI.createWindow({});
141
+ require('window')(win);
142
+ win.open();
143
+ ```
144
+
145
+ ## Platform-specific resources
146
+
147
+ ### Resource overrides system
148
+
149
+ ```javascript
150
+ // Automatically uses the platform-specific version
151
+ const image = Ti.UI.createImageView({
152
+ image: '/images/logo.png' // Will choose the correct file
153
+ });
154
+ ```
155
+
156
+ ### Assets (Alloy)
157
+
158
+ ```
159
+ app/
160
+ ├── assets/
161
+ │ └── images/
162
+ │ └── logo.png // Default
163
+ ├── assets/
164
+ │ └── android/
165
+ │ └── images/
166
+ │ └── logo.png // Android
167
+ └── assets/
168
+ └── iphone/
169
+ └── images/
170
+ └── logo.png // iOS
171
+ ```
172
+
173
+ ## 5. Webpack build pipeline (TiSDK 9.1.0+)
174
+
175
+ Titanium's modern build engine optimizes packaging and allows using npm libraries natively.
176
+
177
+ ### `@` alias
178
+ Use `@` to reference your code root regardless of the current folder depth.
179
+
180
+ ```javascript
181
+ import MyModule from '@/utils/myModule'; // Points to app/lib or src
182
+ ```
183
+
184
+ ### npm support
185
+ Install any npm package in the project root and use it directly with `import`.
186
+
187
+ For more details on optimization, diagnostics, and the build web UI, see `webpack-build-pipeline.md`.
188
+
189
+ ## 6. Internationalization (i18n)
190
+
191
+ ### i18n directory structure
192
+ ```
193
+ i18n/
194
+ ├── en/
195
+ │ ├── strings.xml <!-- Default language -->
196
+ │ └── app.xml <!-- App name localization (Android) -->
197
+ ├── es/
198
+ │ ├── strings.xml
199
+ │ └── app.xml
200
+ └── ja/
201
+ └── strings.xml
202
+ ```
203
+
204
+ Use ISO 639-1 language codes (en, es, ja) and optionally ISO 3166-1 region codes (en-GB, pt-BR).
205
+
206
+ ### strings.xml format
207
+ ```xml
208
+ <?xml version="1.0" encoding="UTF-8"?>
209
+ <resources>
210
+ <string name="welcome_message">Welcome to my app</string>
211
+ <string name="login_button">Log In</string>
212
+ </resources>
213
+ ```
214
+
215
+ ### Using localized strings
216
+
217
+ Basic usage:
218
+ ```javascript
219
+ // Two equivalent methods
220
+ const str1 = L('welcome_message');
221
+ const str2 = Ti.Locale.getString('welcome_message');
222
+
223
+ // With a default fallback
224
+ const withDefault = L('missing_key', 'Default text');
225
+ ```
226
+
227
+ In Alloy XML views, use `titleid` instead of `title`:
228
+ ```xml
229
+ <Button titleid="login_button" />
230
+ <Label textid="welcome_message" />
231
+ ```
232
+
233
+ String formatting:
234
+ ```javascript
235
+ // Simple replacement
236
+ const formatted = String.format(L('format_test'), 'Kevin');
237
+ // Result: "Your name is Kevin"
238
+
239
+ // Ordered replacement
240
+ const formatted = String.format(L('ordered'), 'Jeff', 'Kevin');
241
+ // Result: "Hi Jeff, my name is Kevin"
242
+ ```
243
+
244
+ ### Localizing the app name
245
+
246
+ iOS (SDK 3.2.0+): set `<key>CFBundleDisplayName</key>` in `i18n/LANG/app.xml`
247
+
248
+ Android: use `<string name="appname">Mi App</string>` in `i18n/LANG/strings.xml`
249
+
250
+ ### Localizing images and files
251
+
252
+ Two approaches:
253
+ 1. Platform folders: place localized images in `app/assets/iphone/LANG.lproj/` (iOS) or `app/assets/android/images/` with language qualifiers (Android)
254
+ 2. Code-based: load different assets based on `Ti.Locale.currentLanguage`
255
+
256
+ ### Date and currency formatting
257
+
258
+ ```javascript
259
+ // Date formatting
260
+ const today = new Date();
261
+ const dateStr = String.formatDate(today, 'long');
262
+ const timeStr = String.formatTime(today, 'short');
263
+
264
+ // Currency
265
+ const price = String.formatCurrency(1234.56);
266
+
267
+ // Decimal
268
+ const amount = String.formatDecimal(1234.56);
269
+ ```
270
+
271
+ Warning (Android): `String.formatDate()` may produce incorrect translations or field ordering on some Android versions. Consider using JavaScript `Date` methods as a workaround.
272
+
273
+ ### Testing localizations
274
+
275
+ iOS:
276
+ 1. Settings → General → Language & Region
277
+ 2. Change iPhone Language
278
+ 3. Confirm and restart device
279
+
280
+ Android:
281
+ 1. Settings → Language & input
282
+ 2. Select Language
283
+
284
+ ## Platform-specific APIs
285
+
286
+ ### Example: platform-specific properties
287
+
288
+ ```javascript
289
+ const win = Ti.UI.createWindow({
290
+ // iOS-specific
291
+ barColor: isIOS ? '#007AFF' : null,
292
+ titlePrompt: isIOS ? 'Title' : null,
293
+
294
+ // Android-specific
295
+ softInputMode: isAndroid ? Ti.UI.Android.SOFT_INPUT_ADJUST_PAN : null,
296
+ exitOnClose: isAndroid ? true : false
297
+ });
298
+ ```
299
+
300
+ ## Common cross-platform patterns
301
+
302
+ ### Tab groups
303
+
304
+ ```javascript
305
+ const tabGroup = Ti.UI.createTabGroup();
306
+
307
+ const tab1 = Ti.UI.createTab({
308
+ title: 'Tab 1',
309
+ icon: isIOS ? 'tab1.png' : null, // iOS uses icons
310
+ window: win1
311
+ });
312
+
313
+ tabGroup.addTab(tab1);
314
+ tabGroup.open();
315
+ ```
316
+
317
+ ### Navigation
318
+
319
+ ```javascript
320
+ if (isIOS) {
321
+ // iOS: navigation window with back button
322
+ const nav = Ti.UI.iOS.createNavigationWindow({
323
+ window: win
324
+ });
325
+ nav.open();
326
+ } else if (isAndroid) {
327
+ // Android: open window, use physical button
328
+ win.open();
329
+ }
330
+ ```
331
+
332
+ ### Platform-specific event handling
333
+
334
+ ```javascript
335
+ if (isAndroid) {
336
+ // Android: handle physical Back button
337
+ win.addEventListener('androidback', (e) => {
338
+ // Custom behavior
339
+ alert('Back pressed!');
340
+ });
341
+ }
342
+ ```
343
+
344
+ ## Best practices
345
+
346
+ 1. Test early on both platforms. Do not wait until "porting time".
347
+ 2. Use Alloy. It provides MVC structure and platform abstraction.
348
+ 3. Follow platform conventions. iOS apps should feel like iOS, Android like Android.
349
+ 4. Cache platform checks. Store in variables, do not call `Ti.Platform.osname` repeatedly.
350
+ 5. Use CommonJS modules. Better code organization and reuse.
351
+ 6. Leverage resource overrides. Avoid conditional code for images and assets.
352
+ 7. Think cross-platform from the design phase. UI should adapt gracefully.
353
+
354
+ ## Resources
355
+
356
+ - Alloy Framework - MVC framework for Titanium (see alloy-guides skill)
357
+ - CommonJS Modules - module specification (see coding strategies above)
358
+ - Platform API deep dives - iOS and Android platform-specific features