@maccesar/titools 2.10.0 → 3.1.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-VERCEL-RESEARCH.md +23 -12
- package/README.md +81 -182
- package/agents/ti-pro.md +8 -14
- package/lib/cleanup.js +13 -0
- package/lib/commands/skills.js +2 -1
- package/lib/commands/update.js +4 -1
- package/lib/config.js +9 -11
- package/lib/platform.js +1 -1
- package/package.json +2 -3
- package/skills/purgetss/SKILL.md +12 -0
- package/skills/purgetss/references/animation-advanced.md +0 -9
- package/skills/purgetss/references/app-branding.md +20 -0
- package/skills/purgetss/references/appearance-module.md +85 -27
- package/skills/purgetss/references/apply-directive.md +60 -0
- package/skills/purgetss/references/arbitrary-values.md +41 -0
- package/skills/purgetss/references/cli-commands.md +52 -17
- package/skills/purgetss/references/custom-rules.md +36 -19
- package/skills/purgetss/references/customization-deep-dive.md +37 -15
- package/skills/purgetss/references/grid-layout.md +45 -26
- package/skills/purgetss/references/icon-fonts.md +27 -25
- package/skills/purgetss/references/installation-setup.md +28 -2
- package/skills/purgetss/references/ios-large-titles.md +31 -15
- package/skills/purgetss/references/multi-density-images.md +57 -0
- package/skills/purgetss/references/opacity-modifier.md +11 -2
- package/skills/purgetss/references/semantic-colors.md +44 -1
- package/skills/purgetss/references/tikit-components.md +1 -3
- package/skills/alloy-guides/SKILL.md +0 -190
- package/skills/alloy-guides/references/CLI_TASKS.md +0 -233
- package/skills/alloy-guides/references/CONCEPTS.md +0 -171
- package/skills/alloy-guides/references/CONTROLLERS.md +0 -279
- package/skills/alloy-guides/references/MODELS.md +0 -1214
- package/skills/alloy-guides/references/PURGETSS.md +0 -46
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +0 -235
- package/skills/alloy-guides/references/VIEWS_STYLES.md +0 -375
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +0 -102
- package/skills/alloy-guides/references/VIEWS_XML.md +0 -581
- package/skills/alloy-guides/references/WIDGETS.md +0 -160
- package/skills/alloy-howtos/SKILL.md +0 -181
- package/skills/alloy-howtos/references/best_practices.md +0 -121
- package/skills/alloy-howtos/references/cli_reference.md +0 -230
- package/skills/alloy-howtos/references/config_files.md +0 -158
- package/skills/alloy-howtos/references/custom_tags.md +0 -148
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +0 -78
- package/skills/alloy-howtos/references/samples.md +0 -156
- package/skills/ti-api/SKILL.md +0 -109
- package/skills/ti-api/references/api-android.md +0 -675
- package/skills/ti-api/references/api-app-platform.md +0 -636
- package/skills/ti-api/references/api-core.md +0 -764
- package/skills/ti-api/references/api-data-network.md +0 -641
- package/skills/ti-api/references/api-media.md +0 -655
- package/skills/ti-api/references/api-modules-ble-bluetooth.md +0 -657
- package/skills/ti-api/references/api-modules-coremotion-urlsession.md +0 -411
- package/skills/ti-api/references/api-modules-map.md +0 -632
- package/skills/ti-api/references/api-modules-nfc.md +0 -725
- package/skills/ti-api/references/api-modules-social-misc.md +0 -526
- package/skills/ti-api/references/api-services.md +0 -700
- package/skills/ti-api/references/api-ui-android.md +0 -499
- package/skills/ti-api/references/api-ui-extras.md +0 -702
- package/skills/ti-api/references/api-ui-ios-animator.md +0 -378
- package/skills/ti-api/references/api-ui-ios.md +0 -756
- package/skills/ti-api/references/api-ui-lists.md +0 -581
- package/skills/ti-api/references/api-ui-text-input.md +0 -607
- package/skills/ti-api/references/api-ui-views.md +0 -572
- package/skills/ti-api/references/api-ui-windows-navigation.md +0 -676
- package/skills/ti-api/references/api-xml-global.md +0 -743
- package/skills/ti-guides/SKILL.md +0 -75
- package/skills/ti-guides/references/advanced-data-and-images.md +0 -155
- package/skills/ti-guides/references/android-manifest.md +0 -97
- package/skills/ti-guides/references/app-distribution.md +0 -373
- package/skills/ti-guides/references/application-frameworks.md +0 -366
- package/skills/ti-guides/references/cli-reference.md +0 -700
- package/skills/ti-guides/references/coding-best-practices.md +0 -150
- package/skills/ti-guides/references/commonjs-advanced.md +0 -279
- package/skills/ti-guides/references/hello-world.md +0 -99
- package/skills/ti-guides/references/hyperloop-native-access.md +0 -458
- package/skills/ti-guides/references/javascript-primer.md +0 -402
- package/skills/ti-guides/references/reserved-words.md +0 -36
- package/skills/ti-guides/references/resources.md +0 -172
- package/skills/ti-guides/references/style-and-conventions.md +0 -104
- package/skills/ti-guides/references/tiapp-config.md +0 -655
- package/skills/ti-howtos/SKILL.md +0 -143
- package/skills/ti-howtos/references/android-platform-deep-dives.md +0 -609
- package/skills/ti-howtos/references/automation-fastlane-appium.md +0 -96
- package/skills/ti-howtos/references/buffer-codec-streams.md +0 -162
- package/skills/ti-howtos/references/cross-platform-development.md +0 -358
- package/skills/ti-howtos/references/debugging-profiling.md +0 -473
- package/skills/ti-howtos/references/extending-titanium.md +0 -684
- package/skills/ti-howtos/references/google-maps-v2.md +0 -172
- package/skills/ti-howtos/references/ios-map-kit.md +0 -149
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +0 -595
- package/skills/ti-howtos/references/local-data-sources.md +0 -310
- package/skills/ti-howtos/references/location-and-maps.md +0 -267
- package/skills/ti-howtos/references/media-apis.md +0 -268
- package/skills/ti-howtos/references/notification-services.md +0 -539
- package/skills/ti-howtos/references/remote-data-sources.md +0 -339
- package/skills/ti-howtos/references/tutorials.md +0 -552
- package/skills/ti-howtos/references/using-modules.md +0 -182
- package/skills/ti-howtos/references/web-content-integration.md +0 -288
- package/skills/ti-howtos/references/webpack-build-pipeline.md +0 -125
|
@@ -1,162 +0,0 @@
|
|
|
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.
|
|
@@ -1,358 +0,0 @@
|
|
|
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
|