@maccesar/titools 5.3.0 → 5.4.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/CONTRIBUTING.md +1 -1
- package/README.md +31 -60
- package/agents/ti-pro.md +3 -1
- package/commands/ti-audit.md +6 -4
- package/docs/examples.md +9 -0
- package/docs/knowledge-index.md +2 -1
- package/lib/config.js +1 -0
- package/package.json +1 -1
- package/skills/alloy-guides/SKILL.md +18 -179
- package/skills/alloy-guides/references/CLI_TASKS.md +17 -216
- package/skills/alloy-guides/references/CONCEPTS.md +27 -162
- package/skills/alloy-guides/references/CONTROLLERS.md +38 -236
- package/skills/alloy-guides/references/MODELS.md +47 -723
- package/skills/alloy-guides/references/MODELS_ADVANCED.md +21 -482
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +12 -222
- package/skills/alloy-guides/references/VIEWS_STYLES.md +39 -358
- package/skills/alloy-guides/references/VIEWS_XML.md +36 -552
- package/skills/alloy-guides/references/WIDGETS.md +49 -127
- package/skills/alloy-howtos/SKILL.md +14 -169
- package/skills/alloy-howtos/references/best_practices.md +9 -113
- package/skills/alloy-howtos/references/cli_reference.md +18 -223
- package/skills/alloy-howtos/references/config_files.md +50 -133
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +19 -63
- package/skills/alloy-howtos/references/samples.md +21 -138
- package/skills/ti-api/SKILL.md +10 -2
- package/skills/ti-api/references/api-android.md +36 -2
- package/skills/ti-api/references/api-app-platform.md +39 -3
- package/skills/ti-api/references/api-core.md +50 -18
- package/skills/ti-api/references/api-data-network.md +49 -35
- package/skills/ti-api/references/api-media.md +45 -27
- package/skills/ti-api/references/api-services.md +39 -9
- package/skills/ti-api/references/api-ui-android.md +33 -13
- package/skills/ti-api/references/api-ui-extras.md +41 -15
- package/skills/ti-api/references/api-ui-ios-animator.md +42 -26
- package/skills/ti-api/references/api-ui-ios.md +74 -2
- package/skills/ti-api/references/api-ui-lists.md +32 -16
- package/skills/ti-api/references/api-ui-text-input.md +34 -17
- package/skills/ti-api/references/api-ui-views.md +27 -1
- package/skills/ti-api/references/api-ui-windows-navigation.md +32 -18
- package/skills/ti-api/references/api-xml-global.md +66 -16
- package/skills/ti-create-release/SKILL.md +98 -0
- package/skills/ti-create-release/references/module-discovery.md +69 -0
- package/skills/ti-expert/references/adaptive-layouts.md +1 -1
- package/skills/ti-guides/SKILL.md +37 -76
- package/skills/ti-guides/references/advanced-data-and-images.md +122 -126
- package/skills/ti-guides/references/android-manifest.md +24 -83
- package/skills/ti-guides/references/app-distribution.md +31 -377
- package/skills/ti-guides/references/application-frameworks.md +127 -335
- package/skills/ti-guides/references/cli-reference.md +184 -633
- package/skills/ti-guides/references/commonjs-advanced.md +81 -231
- package/skills/ti-guides/references/compatibility-matrix.md +36 -75
- package/skills/ti-guides/references/hello-world.md +95 -70
- package/skills/ti-guides/references/hyperloop-native-access.md +52 -448
- package/skills/ti-guides/references/resources.md +174 -142
- package/skills/ti-guides/references/sdk-release-notes.md +28 -71
- package/skills/ti-guides/references/tiapp-config.md +222 -598
- package/skills/ti-howtos/SKILL.md +23 -123
- package/skills/ti-howtos/references/cross-platform-development.md +119 -324
- package/skills/ti-howtos/references/debugging-profiling.md +77 -445
- package/skills/ti-howtos/references/extending-titanium.md +199 -673
- package/skills/ti-howtos/references/local-data-sources.md +87 -300
- package/skills/ti-howtos/references/location-and-maps.md +86 -213
- package/skills/ti-howtos/references/media-apis.md +103 -223
- package/skills/ti-howtos/references/notification-services.md +86 -506
- package/skills/ti-howtos/references/remote-data-sources.md +97 -316
- package/skills/ti-howtos/references/using-modules.md +77 -133
- package/skills/ti-ui/SKILL.md +28 -143
- package/skills/ti-ui/references/icons-and-splash-screens.md +74 -403
- package/skills/ti-ui/references/layouts-and-positioning.md +175 -402
- package/skills/ti-ui/references/listviews-and-performance.md +100 -703
- package/skills/ti-ui/references/platform-conventions.md +180 -0
- package/skills/ti-ui/references/user-interface.md +43 -0
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +0 -102
- package/skills/alloy-howtos/references/custom_tags.md +0 -148
- package/skills/ti-guides/references/coding-best-practices.md +0 -149
- package/skills/ti-guides/references/javascript-primer.md +0 -414
- package/skills/ti-guides/references/reserved-words.md +0 -36
- package/skills/ti-guides/references/style-and-conventions.md +0 -103
- package/skills/ti-howtos/references/android-platform-deep-dives.md +0 -624
- 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/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 -611
- package/skills/ti-howtos/references/tutorials.md +0 -565
- package/skills/ti-howtos/references/web-content-integration.md +0 -287
- package/skills/ti-howtos/references/webpack-build-pipeline.md +0 -124
- package/skills/ti-ui/references/accessibility-deep-dive.md +0 -288
- package/skills/ti-ui/references/animation-and-matrices.md +0 -569
- package/skills/ti-ui/references/application-structures.md +0 -626
- package/skills/ti-ui/references/custom-fonts-styling.md +0 -549
- package/skills/ti-ui/references/event-handling.md +0 -401
- package/skills/ti-ui/references/gestures.md +0 -448
- package/skills/ti-ui/references/orientation.md +0 -374
- package/skills/ti-ui/references/platform-ui-android.md +0 -727
- package/skills/ti-ui/references/platform-ui-ios.md +0 -576
- package/skills/ti-ui/references/scrolling-views.md +0 -288
- package/skills/ti-ui/references/tableviews.md +0 -542
|
@@ -1,342 +1,129 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
<!-- TOC-START -->
|
|
4
|
-
## Contents
|
|
5
|
-
|
|
6
|
-
- [1. Filesystem access and storage](#1-filesystem-access-and-storage)
|
|
7
|
-
- [Modules overview](#modules-overview)
|
|
8
|
-
- [Storage locations](#storage-locations)
|
|
9
|
-
- [File operations](#file-operations)
|
|
10
|
-
- [Directory operations](#directory-operations)
|
|
11
|
-
- [Case sensitivity warning](#case-sensitivity-warning)
|
|
12
|
-
- [2. SQLite database](#2-sqlite-database)
|
|
13
|
-
- [Installing a pre-populated database](#installing-a-pre-populated-database)
|
|
14
|
-
- [Opening databases](#opening-databases)
|
|
15
|
-
- [Querying data](#querying-data)
|
|
16
|
-
- [Parameterized queries](#parameterized-queries)
|
|
17
|
-
- [Data modification](#data-modification)
|
|
18
|
-
- [Transactions for batch operations](#transactions-for-batch-operations)
|
|
19
|
-
- [SQLite limitations](#sqlite-limitations)
|
|
20
|
-
- [Disable iCloud backup for databases (iOS)](#disable-icloud-backup-for-databases-ios)
|
|
21
|
-
- [Always close connections](#always-close-connections)
|
|
22
|
-
- [3. Properties API (Ti.App.Properties)](#3-properties-api-tiappproperties)
|
|
23
|
-
- [Overview](#overview)
|
|
24
|
-
- [Data type methods](#data-type-methods)
|
|
25
|
-
- [Usage examples](#usage-examples)
|
|
26
|
-
- [Storing complex objects as JSON](#storing-complex-objects-as-json)
|
|
27
|
-
- [Platform storage](#platform-storage)
|
|
28
|
-
- [4. Advanced data manipulation (Buffer, Codec, and Streams)](#4-advanced-data-manipulation-buffer-codec-and-streams)
|
|
29
|
-
- [5. Choosing a persistence strategy](#5-choosing-a-persistence-strategy)
|
|
30
|
-
- [Decision guide](#decision-guide)
|
|
31
|
-
- [Best practices](#best-practices)
|
|
32
|
-
|
|
33
|
-
<!-- TOC-END -->
|
|
34
|
-
|
|
35
|
-
## 1. Filesystem access and storage
|
|
36
|
-
|
|
37
|
-
### Modules overview
|
|
38
|
-
- `Ti.Filesystem` - top-level module for file/directory operations
|
|
39
|
-
- `Ti.Filesystem.File` - file object with read/write methods
|
|
40
|
-
- `Ti.Filesystem.FileStream` - stream wrapper implementing `Ti.IOStream`
|
|
41
|
-
|
|
42
|
-
### Storage locations
|
|
43
|
-
|
|
44
|
-
| Location | Read/Write | Persistence | Notes |
|
|
45
|
-
| --------------------------- | ---------- | ---------------- | -------------------------------------- |
|
|
46
|
-
| `applicationDataDirectory` | R/W | Until uninstall | Primary app data location |
|
|
47
|
-
| `resourcesDirectory` | R-only | Until uninstall | App resources (R/W in simulator only) |
|
|
48
|
-
| `tempDirectory` | R/W | Until app closes | OS may delete anytime |
|
|
49
|
-
| `applicationCacheDirectory` | R/W | OS may clean | For cached data |
|
|
50
|
-
| `externalCacheDirectory` | R/W | OS may clean | Android SD card cache |
|
|
51
|
-
| `externalStorageDirectory` | R/W | Until uninstall | Android SD card storage |
|
|
52
|
-
|
|
53
|
-
Always check `Ti.Filesystem.isExternalStoragePresent()` before using external storage on Android.
|
|
54
|
-
|
|
55
|
-
### File operations
|
|
56
|
-
|
|
57
|
-
#### Getting a file handle
|
|
58
|
-
```javascript
|
|
59
|
-
const f = Ti.Filesystem.getFile(
|
|
60
|
-
Ti.Filesystem.applicationDataDirectory,
|
|
61
|
-
'myfile.txt'
|
|
62
|
-
);
|
|
63
|
-
```
|
|
1
|
+
# Working with data
|
|
64
2
|
|
|
65
|
-
|
|
66
|
-
```javascript
|
|
67
|
-
f.write('Content here'); // Overwrites or creates
|
|
68
|
-
```
|
|
3
|
+
Based on the [current official guide](https://titaniumsdk.com/docs/build/data.md). Examples target released SDK 13.4.1; verify the selected SDK before adopting version-specific behavior.
|
|
69
4
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const contents = f.read(); // Returns Blob
|
|
73
|
-
Ti.API.info(contents.text); // Text content
|
|
74
|
-
Ti.API.info(contents.mimeType); // MIME type
|
|
75
|
-
```
|
|
5
|
+
Titanium gives you three places to keep data on the device, and the whole
|
|
6
|
+
decision is how much of it there is and what shape it has.
|
|
76
7
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
8
|
+
| Store | For | Survives an uninstall |
|
|
9
|
+
| ----- | --- | --------------------- |
|
|
10
|
+
| `Ti.App.Properties` | Settings and small values | No |
|
|
11
|
+
| `Ti.Filesystem` | Files, downloads, generated content | No |
|
|
12
|
+
| `Ti.Database` | Rows you query | No |
|
|
81
13
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// Auto-creates on write, but explicit option exists:
|
|
85
|
-
if (!f.exists()) {
|
|
86
|
-
f.createFile();
|
|
87
|
-
}
|
|
14
|
+
None of them survive an uninstall. Anything that must is on a server, and
|
|
15
|
+
[networking](https://titaniumsdk.com/docs/build/data/networking.md) is how it gets there.
|
|
88
16
|
|
|
89
|
-
|
|
90
|
-
const oldFile = Ti.Filesystem.getFile(applicationDataDirectory, 'old.txt');
|
|
91
|
-
oldFile.copy(`${applicationDataDirectory}new.txt`);
|
|
17
|
+
## Properties
|
|
92
18
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
```
|
|
19
|
+
Key-value storage for small things: the last tab, a token, whether the user has
|
|
20
|
+
seen the tour. It is backed by `NSUserDefaults` on iOS and `SharedPreferences`
|
|
21
|
+
on Android, and it is read synchronously.
|
|
97
22
|
|
|
98
|
-
|
|
99
|
-
|
|
23
|
+
```js
|
|
24
|
+
Ti.App.Properties.setString('lastTab', 'inbox');
|
|
25
|
+
Ti.App.Properties.setBool('seenTour', true);
|
|
100
26
|
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
f.rename('new.txt');
|
|
104
|
-
// f still references 'old.txt' (now non-existent)
|
|
105
|
-
const newf = Ti.Filesystem.getFile(applicationDataDirectory, 'new.txt');
|
|
27
|
+
const tab = Ti.App.Properties.getString('lastTab', 'inbox');
|
|
28
|
+
const seen = Ti.App.Properties.getBool('seenTour', false);
|
|
106
29
|
```
|
|
107
30
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (f.exists() && f.writable) {
|
|
111
|
-
const success = f.deleteFile(); // Returns Boolean, no error thrown
|
|
112
|
-
}
|
|
113
|
-
```
|
|
31
|
+
Every getter takes a default as its second argument. Use it rather than
|
|
32
|
+
checking `hasProperty` first, which is a second lookup for the same answer.
|
|
114
33
|
|
|
115
|
-
|
|
34
|
+
There is a setter and getter per type - `setString`, `setInt`, `setBool`,
|
|
35
|
+
`setDouble`, `setList`, `setObject` - and reading with the wrong one does not
|
|
36
|
+
convert. Store with `setInt` and read with `getString` and you get the default
|
|
37
|
+
back.
|
|
116
38
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const dir = Ti.Filesystem.getFile(applicationDataDirectory, 'mysubdir');
|
|
120
|
-
dir.createDirectory();
|
|
39
|
+
`setObject` and `setList` serialise to JSON, so they are for a handful of
|
|
40
|
+
values, not a collection you keep adding to.
|
|
121
41
|
|
|
122
|
-
|
|
123
|
-
|
|
42
|
+
> [!WARNING]
|
|
43
|
+
> Properties are not secure storage. They are plain preferences, readable on a
|
|
44
|
+
> rooted or jailbroken device and included in an unencrypted device backup. A
|
|
45
|
+
> token you would mind losing belongs in the keychain or keystore, which is a
|
|
46
|
+
> native module rather than a core API.
|
|
124
47
|
|
|
125
|
-
|
|
126
|
-
const file = Ti.Filesystem.getFile(applicationDataDirectory, 'file.txt');
|
|
127
|
-
file.move('mysubdir/file.txt');
|
|
48
|
+
## Files
|
|
128
49
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
dir.deleteDirectory(true); // Recursive delete
|
|
132
|
-
```
|
|
50
|
+
`Ti.Filesystem` addresses directories by purpose, and the purpose decides
|
|
51
|
+
whether the operating system may delete what you put there.
|
|
133
52
|
|
|
134
|
-
|
|
135
|
-
|
|
53
|
+
| Directory | Use for | Backed up |
|
|
54
|
+
| --------- | ------- | --------- |
|
|
55
|
+
| `applicationDataDirectory` | Content the app created and needs | Yes |
|
|
56
|
+
| `applicationCacheDirectory` | Anything re-downloadable | No, and may be purged |
|
|
57
|
+
| `tempDirectory` | Working files for right now | No |
|
|
58
|
+
| `resourcesDirectory` | What you shipped. **Read-only** | n/a |
|
|
136
59
|
|
|
137
|
-
|
|
60
|
+
```js
|
|
61
|
+
const file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'notes.txt');
|
|
62
|
+
file.write('written on ' + new Date().toISOString());
|
|
138
63
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
// Copies db from Resources/ (or app/assets/) to applicationDataDirectory
|
|
143
|
-
const db = Ti.Database.install('seeds/mydata.sqlite', 'mydata');
|
|
144
|
-
// On subsequent launches, install() just opens the existing database
|
|
64
|
+
if (file.exists()) {
|
|
65
|
+
Ti.API.info(file.read().text);
|
|
66
|
+
}
|
|
145
67
|
```
|
|
146
68
|
|
|
147
|
-
|
|
69
|
+
`getFile` takes path segments and joins them, so pass the directory and the
|
|
70
|
+
name rather than concatenating with a separator yourself.
|
|
148
71
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const db = Ti.Database.install('mydb.sqlite', 'myInstalledDB');
|
|
72
|
+
Putting a cache in `applicationDataDirectory` is the common mistake: it is
|
|
73
|
+
backed up, so a 200MB image cache goes into the user's iCloud backup.
|
|
152
74
|
|
|
153
|
-
|
|
154
|
-
const db = Ti.Database.open('myDatabase');
|
|
75
|
+
## A database
|
|
155
76
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
);
|
|
161
|
-
const db = Ti.Database.open(dbFile.nativePath);
|
|
162
|
-
```
|
|
77
|
+
`Ti.Database` is SQLite. Open a database by name and it is created on first
|
|
78
|
+
use.
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
const db = Ti.Database.open('notes');
|
|
163
82
|
|
|
164
|
-
|
|
83
|
+
db.execute(`
|
|
84
|
+
CREATE TABLE IF NOT EXISTS notes (
|
|
85
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
86
|
+
body TEXT NOT NULL,
|
|
87
|
+
created TEXT NOT NULL
|
|
88
|
+
)
|
|
89
|
+
`);
|
|
165
90
|
|
|
166
|
-
|
|
167
|
-
|
|
91
|
+
db.execute('INSERT INTO notes (body, created) VALUES (?, ?)', 'First note', new Date().toISOString());
|
|
92
|
+
Ti.API.info(`inserted row ${db.lastInsertRowId}`);
|
|
168
93
|
|
|
94
|
+
const rows = db.execute('SELECT id, body FROM notes ORDER BY id DESC');
|
|
169
95
|
while (rows.isValidRow()) {
|
|
170
|
-
Ti.API.info(rows.fieldByName('
|
|
171
|
-
Ti.API.info(rows.field(0)); // First column by index
|
|
96
|
+
Ti.API.info(`${rows.fieldByName('id')}: ${rows.fieldByName('body')}`);
|
|
172
97
|
rows.next();
|
|
173
98
|
}
|
|
174
|
-
|
|
175
|
-
// Always close result set
|
|
176
99
|
rows.close();
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Parameterized queries
|
|
180
|
-
Always use parameters to prevent SQL injection:
|
|
181
|
-
|
|
182
|
-
```javascript
|
|
183
|
-
// Safe - parameterized
|
|
184
|
-
db.execute('INSERT INTO users (name, age) VALUES (?, ?)', ['John', 25]);
|
|
185
|
-
|
|
186
|
-
// Unsafe - never do this
|
|
187
|
-
db.execute(`INSERT INTO users (name, age) VALUES ('${name}', ${age})`);
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Data modification
|
|
191
|
-
|
|
192
|
-
```javascript
|
|
193
|
-
// INSERT
|
|
194
|
-
db.execute('INSERT INTO users (name, age) VALUES (?, ?)', ['Jane', 30]);
|
|
195
|
-
const lastId = db.lastInsertRowId; // ID of the last inserted row
|
|
196
|
-
const affected = db.rowsAffected; // number of rows changed by last statement
|
|
197
|
-
|
|
198
|
-
// UPDATE
|
|
199
|
-
db.execute('UPDATE users SET age = ? WHERE name = ?', [31, 'Jane']);
|
|
200
|
-
const rowsAffected = db.rowsAffected;
|
|
201
|
-
|
|
202
|
-
// DELETE
|
|
203
|
-
db.execute('DELETE FROM users WHERE age < ?', [18]);
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### Transactions for batch operations
|
|
207
|
-
Use transactions to speed up multiple inserts or updates:
|
|
208
|
-
```javascript
|
|
209
|
-
const db = Ti.Database.open('mydb');
|
|
210
|
-
db.execute('BEGIN');
|
|
211
|
-
try {
|
|
212
|
-
for (let i = 0; i < items.length; i++) {
|
|
213
|
-
db.execute('INSERT INTO products (name, price) VALUES (?, ?)', items[i].name, items[i].price);
|
|
214
|
-
}
|
|
215
|
-
db.execute('COMMIT');
|
|
216
|
-
} catch (e) {
|
|
217
|
-
db.execute('ROLLBACK');
|
|
218
|
-
Ti.API.error(`Transaction failed: ${e.message}`);
|
|
219
|
-
}
|
|
220
|
-
db.close();
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Performance: wrapping 1000 inserts in a transaction can be 10-100x faster than individual inserts.
|
|
224
|
-
|
|
225
|
-
### SQLite limitations
|
|
226
|
-
- No `FULL OUTER JOIN` support. Use `LEFT JOIN` with `UNION`.
|
|
227
|
-
- Limited `ALTER TABLE`. You can only `ADD COLUMN` or `RENAME TABLE`.
|
|
228
|
-
- No built-in referential integrity (foreign keys). Enable with `PRAGMA foreign_keys = ON`.
|
|
229
|
-
- No native boolean type. Use INTEGER (0/1).
|
|
230
|
-
|
|
231
|
-
### Disable iCloud backup for databases (iOS)
|
|
232
|
-
|
|
233
|
-
iOS backs up databases to iCloud by default. For large or recreatable databases, disable this:
|
|
234
|
-
```javascript
|
|
235
|
-
const db = Ti.Database.open('mydb');
|
|
236
|
-
db.file.setRemoteBackup(false);
|
|
237
100
|
db.close();
|
|
238
101
|
```
|
|
239
102
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
```javascript
|
|
245
|
-
try {
|
|
246
|
-
// Database operations
|
|
247
|
-
} finally {
|
|
248
|
-
// Always close, even on error
|
|
249
|
-
if (rows) rows.close();
|
|
250
|
-
if (db) db.close();
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
## 3. Properties API (Ti.App.Properties)
|
|
255
|
-
|
|
256
|
-
### Overview
|
|
257
|
-
Lightweight key-value storage for simple data types. Loaded into memory at launch for fast access.
|
|
258
|
-
|
|
259
|
-
Warning: there is no hard limit, but all properties load into memory. Avoid storing large data.
|
|
260
|
-
|
|
261
|
-
### Data type methods
|
|
103
|
+
**Pass values as arguments, never by building the SQL string.** The `?`
|
|
104
|
+
placeholders are escaped for you; string concatenation is how an apostrophe in
|
|
105
|
+
a note becomes a syntax error and how a hostile value becomes an injection.
|
|
262
106
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
| String | `getString(name, default)` | `setString(name, value)` |
|
|
266
|
-
| Int | `getInt(name, default)` | `setInt(name, value)` |
|
|
267
|
-
| Double | `getDouble(name, default)` | `setDouble(name, value)` |
|
|
268
|
-
| Bool | `getBool(name, default)` | `setBool(name, value)` |
|
|
269
|
-
| List | `getList(name, default)` | `setList(name, value)` |
|
|
107
|
+
A result set is a cursor, not an array: walk it with `isValidRow()` and
|
|
108
|
+
`next()`, and close it. Close the database when you are done with it.
|
|
270
109
|
|
|
271
|
-
|
|
110
|
+
`executeAsync` and `executeAllAsync` run off the main thread and take a
|
|
111
|
+
callback. Use them for anything large enough to be noticeable, which on a
|
|
112
|
+
phone is sooner than you would guess.
|
|
272
113
|
|
|
273
|
-
|
|
274
|
-
// Set values
|
|
275
|
-
Ti.App.Properties.setString('username', 'john');
|
|
276
|
-
Ti.App.Properties.setInt('loginCount', 5);
|
|
277
|
-
Ti.App.Properties.setBool('isLoggedIn', true);
|
|
278
|
-
Ti.App.Properties.setDouble('price', 19.99);
|
|
279
|
-
Ti.App.Properties.setList('favorites', ['item1', 'item2']);
|
|
114
|
+
### Shipping a prepared database
|
|
280
115
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const count = Ti.App.Properties.getInt('loginCount', 0);
|
|
116
|
+
`Ti.Database.install` copies a `.sqlite` file out of your resources on first
|
|
117
|
+
run and opens it, so an app can ship with data already in it.
|
|
284
118
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// ...
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Remove property
|
|
291
|
-
Ti.App.Properties.removeProperty('username');
|
|
292
|
-
|
|
293
|
-
// List all properties
|
|
294
|
-
const allProps = Ti.App.Properties.listProperties();
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
### Storing complex objects as JSON
|
|
298
|
-
|
|
299
|
-
```javascript
|
|
300
|
-
// Store object as JSON string
|
|
301
|
-
const data = { city: 'Mountain View', temp: 72 };
|
|
302
|
-
Ti.App.Properties.setString('weatherData', JSON.stringify(data));
|
|
303
|
-
|
|
304
|
-
// Retrieve and parse
|
|
305
|
-
const stored = Ti.App.Properties.getString('weatherData', '{}');
|
|
306
|
-
const weather = JSON.parse(stored);
|
|
307
|
-
Ti.API.info(weather.city); // 'Mountain View'
|
|
119
|
+
```js
|
|
120
|
+
const db = Ti.Database.install('/data/seed.sqlite', 'notes');
|
|
308
121
|
```
|
|
309
122
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
- Android: XML file at `/data/data/com.domain.app/shared_prefs/titanium.xml`
|
|
313
|
-
|
|
314
|
-
## 4. Advanced data manipulation (Buffer, Codec, and Streams)
|
|
315
|
-
|
|
316
|
-
For binary data handling, character encoding, and large file streams, see:
|
|
317
|
-
|
|
318
|
-
- Buffer, Codec, and Streams: `buffer-codec-streams.md`
|
|
319
|
-
|
|
320
|
-
## 5. Choosing a persistence strategy
|
|
321
|
-
|
|
322
|
-
### Decision guide
|
|
323
|
-
|
|
324
|
-
| Scenario | Recommended approach |
|
|
325
|
-
| ---------------------------------- | ---------------------------------------- |
|
|
326
|
-
| User settings/preferences | `Ti.App.Properties` |
|
|
327
|
-
| Small config data (< 100KB) | `Ti.App.Properties` with JSON |
|
|
328
|
-
| Structured relational data | SQLite |
|
|
329
|
-
| Large binary data (images, videos) | Filesystem |
|
|
330
|
-
| Downloaded content cache | Filesystem (`applicationCacheDirectory`) |
|
|
331
|
-
| Temporary processing data | Filesystem (`tempDirectory`) |
|
|
332
|
-
| User-generated files | Filesystem (`applicationDataDirectory`) |
|
|
333
|
-
| Offline-first app data | SQLite + Filesystem combo |
|
|
123
|
+
The copy happens once. Changing the shipped file in a later release does not
|
|
124
|
+
replace a database the user already has, so version your schema and migrate.
|
|
334
125
|
|
|
335
|
-
|
|
126
|
+
## Next
|
|
336
127
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
3. Filesystem: check external storage availability on Android; handle case sensitivity.
|
|
340
|
-
4. Streams: use for large file operations to avoid memory issues.
|
|
341
|
-
5. Hybrid approach: store metadata in SQLite, file paths in records, actual files on filesystem.
|
|
342
|
-
6. Cleanup: implement cleanup for temp files and cache; do not let them accumulate.
|
|
128
|
+
[Networking and remote data](https://titaniumsdk.com/docs/build/data/networking.md) is the other half:
|
|
129
|
+
getting data in and out over HTTP.
|