@maccesar/titools 2.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.
- package/AGENTS-TEMPLATE.md +173 -0
- package/README.md +867 -0
- package/agents/ti-researcher.md +108 -0
- package/bin/titools.js +53 -0
- package/lib/commands/agents.js +126 -0
- package/lib/commands/install.js +188 -0
- package/lib/commands/uninstall.js +215 -0
- package/lib/commands/update.js +159 -0
- package/lib/config.js +119 -0
- package/lib/downloader.js +153 -0
- package/lib/installer.js +253 -0
- package/lib/platform.js +108 -0
- package/lib/symlink.js +142 -0
- package/lib/utils.js +270 -0
- package/package.json +67 -0
- package/skills/alloy-expert/SKILL.md +247 -0
- package/skills/alloy-expert/assets/ControllerAutoCleanup.js +182 -0
- package/skills/alloy-expert/references/alloy-structure.md +381 -0
- package/skills/alloy-expert/references/anti-patterns.md +133 -0
- package/skills/alloy-expert/references/code-conventions.md +469 -0
- package/skills/alloy-expert/references/contracts.md +280 -0
- package/skills/alloy-expert/references/controller-patterns.md +520 -0
- package/skills/alloy-expert/references/error-handling.md +484 -0
- package/skills/alloy-expert/references/examples.md +735 -0
- package/skills/alloy-expert/references/migration-patterns.md +298 -0
- package/skills/alloy-expert/references/patterns.md +448 -0
- package/skills/alloy-expert/references/performance-patterns.md +855 -0
- package/skills/alloy-expert/references/security-patterns.md +847 -0
- package/skills/alloy-expert/references/state-management.md +779 -0
- package/skills/alloy-expert/references/testing.md +872 -0
- package/skills/alloy-guides/SKILL.md +214 -0
- package/skills/alloy-guides/references/CLI_TASKS.md +243 -0
- package/skills/alloy-guides/references/CONCEPTS.md +191 -0
- package/skills/alloy-guides/references/CONTROLLERS.md +298 -0
- package/skills/alloy-guides/references/MODELS.md +1028 -0
- package/skills/alloy-guides/references/PURGETSS.md +56 -0
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +242 -0
- package/skills/alloy-guides/references/VIEWS_STYLES.md +388 -0
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +109 -0
- package/skills/alloy-guides/references/VIEWS_XML.md +558 -0
- package/skills/alloy-guides/references/WIDGETS.md +176 -0
- package/skills/alloy-howtos/SKILL.md +203 -0
- package/skills/alloy-howtos/references/best_practices.md +138 -0
- package/skills/alloy-howtos/references/cli_reference.md +253 -0
- package/skills/alloy-howtos/references/config_files.md +87 -0
- package/skills/alloy-howtos/references/custom_tags.md +147 -0
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +101 -0
- package/skills/alloy-howtos/references/samples.md +167 -0
- package/skills/purgetss/SKILL.md +442 -0
- package/skills/purgetss/assets/purgetss.config.cjs +17 -0
- package/skills/purgetss/references/EXAMPLES.md +247 -0
- package/skills/purgetss/references/animation-system.md +1294 -0
- package/skills/purgetss/references/apply-directive.md +375 -0
- package/skills/purgetss/references/arbitrary-values.md +612 -0
- package/skills/purgetss/references/class-index.md +1350 -0
- package/skills/purgetss/references/cli-commands.md +948 -0
- package/skills/purgetss/references/configurable-properties.md +654 -0
- package/skills/purgetss/references/custom-rules.md +161 -0
- package/skills/purgetss/references/customization-deep-dive.md +722 -0
- package/skills/purgetss/references/dynamic-component-creation.md +489 -0
- package/skills/purgetss/references/grid-layout.md +455 -0
- package/skills/purgetss/references/icon-fonts.md +609 -0
- package/skills/purgetss/references/installation-setup.md +366 -0
- package/skills/purgetss/references/opacity-modifier.md +291 -0
- package/skills/purgetss/references/platform-modifiers.md +479 -0
- package/skills/purgetss/references/smart-mappings.md +42 -0
- package/skills/purgetss/references/titanium-resets.md +359 -0
- package/skills/purgetss/references/ui-ux-design.md +1526 -0
- package/skills/ti-guides/SKILL.md +94 -0
- package/skills/ti-guides/references/advanced-data-and-images.md +19 -0
- package/skills/ti-guides/references/alloy-cli-advanced.md +84 -0
- package/skills/ti-guides/references/alloy-data-mastery.md +29 -0
- package/skills/ti-guides/references/alloy-widgets-and-themes.md +19 -0
- package/skills/ti-guides/references/android-manifest.md +97 -0
- package/skills/ti-guides/references/app-distribution.md +258 -0
- package/skills/ti-guides/references/application-frameworks.md +377 -0
- package/skills/ti-guides/references/cli-reference.md +402 -0
- package/skills/ti-guides/references/coding-best-practices.md +102 -0
- package/skills/ti-guides/references/commonjs-advanced.md +134 -0
- package/skills/ti-guides/references/hello-world.md +100 -0
- package/skills/ti-guides/references/hyperloop-native-access.md +62 -0
- package/skills/ti-guides/references/javascript-primer.md +411 -0
- package/skills/ti-guides/references/reserved-words.md +36 -0
- package/skills/ti-guides/references/resources.md +183 -0
- package/skills/ti-guides/references/style-and-conventions.md +48 -0
- package/skills/ti-guides/references/tiapp-config.md +609 -0
- package/skills/ti-howtos/SKILL.md +174 -0
- package/skills/ti-howtos/references/android-platform-deep-dives.md +658 -0
- package/skills/ti-howtos/references/automation-fastlane-appium.md +95 -0
- package/skills/ti-howtos/references/buffer-codec-streams.md +140 -0
- package/skills/ti-howtos/references/cross-platform-development.md +348 -0
- package/skills/ti-howtos/references/debugging-profiling.md +543 -0
- package/skills/ti-howtos/references/extending-titanium.md +723 -0
- package/skills/ti-howtos/references/google-maps-v2.md +169 -0
- package/skills/ti-howtos/references/ios-map-kit.md +143 -0
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +783 -0
- package/skills/ti-howtos/references/local-data-sources.md +301 -0
- package/skills/ti-howtos/references/location-and-maps.md +252 -0
- package/skills/ti-howtos/references/media-apis.md +210 -0
- package/skills/ti-howtos/references/notification-services.md +599 -0
- package/skills/ti-howtos/references/remote-data-sources.md +349 -0
- package/skills/ti-howtos/references/tutorials.md +502 -0
- package/skills/ti-howtos/references/using-modules.md +237 -0
- package/skills/ti-howtos/references/web-content-integration.md +307 -0
- package/skills/ti-howtos/references/webpack-build-pipeline.md +78 -0
- package/skills/ti-ui/SKILL.md +179 -0
- package/skills/ti-ui/references/accessibility-deep-dive.md +242 -0
- package/skills/ti-ui/references/animation-and-matrices.md +599 -0
- package/skills/ti-ui/references/application-structures.md +655 -0
- package/skills/ti-ui/references/custom-fonts-styling.md +579 -0
- package/skills/ti-ui/references/event-handling.md +393 -0
- package/skills/ti-ui/references/gestures.md +473 -0
- package/skills/ti-ui/references/icons-and-splash-screens.md +409 -0
- package/skills/ti-ui/references/layouts-and-positioning.md +462 -0
- package/skills/ti-ui/references/listviews-and-performance.md +619 -0
- package/skills/ti-ui/references/orientation.md +362 -0
- package/skills/ti-ui/references/platform-ui-android.md +635 -0
- package/skills/ti-ui/references/platform-ui-ios.md +469 -0
- package/skills/ti-ui/references/scrolling-views.md +252 -0
- package/skills/ti-ui/references/tableviews.md +568 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# Remote Data Sources
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Remote Data Sources](#remote-data-sources)
|
|
6
|
+
- [Table of Contents](#table-of-contents)
|
|
7
|
+
- [1. HTTPClient and Request Lifecycle](#1-httpclient-and-request-lifecycle)
|
|
8
|
+
- [Basic Pattern](#basic-pattern)
|
|
9
|
+
- [HTTP Methods](#http-methods)
|
|
10
|
+
- [Setting Headers](#setting-headers)
|
|
11
|
+
- [XHR Lifecycle States](#xhr-lifecycle-states)
|
|
12
|
+
- [Progress Monitoring](#progress-monitoring)
|
|
13
|
+
- [2. Working with JSON Data](#2-working-with-json-data)
|
|
14
|
+
- [Receiving JSON](#receiving-json)
|
|
15
|
+
- [Sending JSON](#sending-json)
|
|
16
|
+
- [Important Limitation](#important-limitation)
|
|
17
|
+
- [3. Working with XML Data](#3-working-with-xml-data)
|
|
18
|
+
- [Parsing XML](#parsing-xml)
|
|
19
|
+
- [Common DOM Methods](#common-dom-methods)
|
|
20
|
+
- [Important: Know Your DTD](#important-know-your-dtd)
|
|
21
|
+
- [4. File Uploads and Downloads](#4-file-uploads-and-downloads)
|
|
22
|
+
- [File Upload](#file-upload)
|
|
23
|
+
- [File Download (Cross-Platform)](#file-download-cross-platform)
|
|
24
|
+
- [File Storage Locations](#file-storage-locations)
|
|
25
|
+
- [5. Sockets](#5-sockets)
|
|
26
|
+
- [Creating a TCP Socket](#creating-a-tcp-socket)
|
|
27
|
+
- [Socket Listening (Android/iOS)](#socket-listening-androidios)
|
|
28
|
+
- [6. Dealing with SOAP Web Services](#6-dealing-with-soap-web-services)
|
|
29
|
+
- [Manual Approach (SOAP Envelope)](#manual-approach-soap-envelope)
|
|
30
|
+
- [7. SSL Certificate \& Security Manager](#7-ssl-certificate--security-manager)
|
|
31
|
+
- [SSL Pinning (TiSDK 3.3.0+)](#ssl-pinning-tisdk-330)
|
|
32
|
+
- [Android: addTrustManager](#android-addtrustmanager)
|
|
33
|
+
- [CORS Considerations for Mobile Web](#cors-considerations-for-mobile-web)
|
|
34
|
+
- [Best Practices](#best-practices)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 1. HTTPClient and Request Lifecycle
|
|
39
|
+
|
|
40
|
+
### Basic Pattern
|
|
41
|
+
`Ti.Network.HTTPClient` mirrors XHR (XMLHttpRequest) API. Always handle both success and error cases.
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
const xhr = Ti.Network.createHTTPClient({
|
|
45
|
+
onload: (e) => {
|
|
46
|
+
// this.responseText - raw text (for JSON/text)
|
|
47
|
+
// this.responseXML - XML document (including SOAP)
|
|
48
|
+
// this.responseData - binary data (Blob)
|
|
49
|
+
Ti.API.debug(xhr.responseText);
|
|
50
|
+
},
|
|
51
|
+
onerror: (e) => {
|
|
52
|
+
Ti.API.debug(e.error);
|
|
53
|
+
},
|
|
54
|
+
timeout: 5000
|
|
55
|
+
});
|
|
56
|
+
xhr.open('GET', 'https://api.example.com/data');
|
|
57
|
+
xhr.send();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### HTTP Methods
|
|
61
|
+
- GET: `xhr.open('GET', url)` then `xhr.send()`
|
|
62
|
+
- POST: `xhr.open('POST', url)` then `xhr.send({key: 'value'})`
|
|
63
|
+
- PUT/DELETE/PATCH: All supported (PATCH since 4.1.0 on Android)
|
|
64
|
+
|
|
65
|
+
### Setting Headers
|
|
66
|
+
**Critical**: Headers must be set AFTER `open()` but BEFORE `send()`
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
const client = Ti.Network.createHTTPClient();
|
|
70
|
+
client.open('POST', 'http://server.com/upload');
|
|
71
|
+
client.setRequestHeader('Content-Type', 'text/csv');
|
|
72
|
+
client.setRequestHeader('Authorization', `Bearer ${token}`);
|
|
73
|
+
client.send('data');
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### XHR Lifecycle States
|
|
77
|
+
Monitor with `onreadystatechange`:
|
|
78
|
+
- `UNSENT` - Object constructed
|
|
79
|
+
- `OPENED` - `open()` called successfully
|
|
80
|
+
- `HEADERS_RECEIVED` - All redirects followed, headers received
|
|
81
|
+
- `LOADING` - Response body being received
|
|
82
|
+
- `DONE` - Transfer complete or error occurred
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
xhr.onreadystatechange = (e) => {
|
|
86
|
+
switch(xhr.readyState) {
|
|
87
|
+
case Ti.Network.HTTPClient.HEADERS_RECEIVED:
|
|
88
|
+
Ti.API.info(`Headers: ${xhr.getResponseHeader('Content-Type')}`);
|
|
89
|
+
break;
|
|
90
|
+
case Ti.Network.HTTPClient.DONE:
|
|
91
|
+
Ti.API.info('Complete');
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Progress Monitoring
|
|
98
|
+
- `onsendstream`: Upload progress (0.0-1.0)
|
|
99
|
+
- `ondatastream`: Download progress (0.0-1.0)
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
xhr.onsendstream = (e) => {
|
|
103
|
+
progressBar.value = e.progress;
|
|
104
|
+
};
|
|
105
|
+
xhr.ondatastream = (e) => {
|
|
106
|
+
progressBar.value = e.progress;
|
|
107
|
+
};
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 2. Working with JSON Data
|
|
111
|
+
|
|
112
|
+
### Receiving JSON
|
|
113
|
+
```javascript
|
|
114
|
+
xhr.onload = () => {
|
|
115
|
+
const data = JSON.parse(xhr.responseText);
|
|
116
|
+
Ti.API.info(data.users[0].name);
|
|
117
|
+
};
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Sending JSON
|
|
121
|
+
`send()` automatically stringifies objects:
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
const postData = { title: 'My Post', body: 'Content' };
|
|
125
|
+
xhr.open('POST', 'http://blog.com/api/posts');
|
|
126
|
+
xhr.send(postData); // Auto-stringified
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
For GET querystrings, manually stringify and encode:
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
const data = { search: 'titanium' };
|
|
133
|
+
const queryString = encodeURIComponent(JSON.stringify(data));
|
|
134
|
+
xhr.open('GET', `http://api.com/search?q=${queryString}`);
|
|
135
|
+
xhr.send();
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Important Limitation
|
|
139
|
+
JSON cannot represent methods. Attempting to stringify Titanium objects returns empty representation.
|
|
140
|
+
|
|
141
|
+
## 3. Working with XML Data
|
|
142
|
+
|
|
143
|
+
### Parsing XML
|
|
144
|
+
Titanium provides XML DOM Level 2 implementation. Auto-serializes if Content-Type is XML.
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
xhr.onload = () => {
|
|
148
|
+
const doc = xhr.responseXML.documentElement;
|
|
149
|
+
const items = doc.getElementsByTagName('item');
|
|
150
|
+
for (let i = 0; i < items.length; i++) {
|
|
151
|
+
const title = items.item(i)
|
|
152
|
+
.getElementsByTagName('title').item(0)
|
|
153
|
+
.textContent;
|
|
154
|
+
Ti.API.info(title);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Common DOM Methods
|
|
160
|
+
- `getElementsByTagName(name)` - Returns array of nodes
|
|
161
|
+
- `item(index)` - Select specific node from array
|
|
162
|
+
- `getAttribute(name)` - Get attribute value
|
|
163
|
+
- `textContent` / `nodeValue` - Get leaf node value
|
|
164
|
+
|
|
165
|
+
### Important: Know Your DTD
|
|
166
|
+
You must understand the XML structure (node hierarchy) to parse correctly. Use tools like apigee.com to inspect API responses.
|
|
167
|
+
|
|
168
|
+
## 4. File Uploads and Downloads
|
|
169
|
+
|
|
170
|
+
### File Upload
|
|
171
|
+
Pass a Blob to `send()`:
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
Ti.Media.openPhotoGallery({
|
|
175
|
+
success: (event) => {
|
|
176
|
+
const xhr = Ti.Network.createHTTPClient({
|
|
177
|
+
onload: () => {
|
|
178
|
+
Ti.API.info(`Upload complete: ${xhr.status}`);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
xhr.open('POST', 'https://server.com/upload');
|
|
182
|
+
xhr.send({
|
|
183
|
+
file: event.media, // Blob from gallery
|
|
184
|
+
username: 'user'
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
For file uploads with actual file contents:
|
|
191
|
+
```javascript
|
|
192
|
+
const file = Ti.Filesystem.getFile(event.media.nativePath);
|
|
193
|
+
if (file.exists()) {
|
|
194
|
+
xhr.send({ file: file.read() });
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### File Download (Cross-Platform)
|
|
199
|
+
|
|
200
|
+
**Option 1**: Write manually to filesystem
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
const xhr = Ti.Network.createHTTPClient({
|
|
204
|
+
onload: () => {
|
|
205
|
+
const file = Ti.Filesystem.getFile(
|
|
206
|
+
Ti.Filesystem.applicationDataDirectory,
|
|
207
|
+
'downloaded.png'
|
|
208
|
+
);
|
|
209
|
+
file.write(xhr.responseData);
|
|
210
|
+
Ti.App.fireEvent('download_complete', { path: file.nativePath });
|
|
211
|
+
},
|
|
212
|
+
timeout: 10000
|
|
213
|
+
});
|
|
214
|
+
xhr.open('GET', 'http://example.com/image.png');
|
|
215
|
+
xhr.send();
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Option 2**: iOS-only automatic saving with `file` property
|
|
219
|
+
|
|
220
|
+
```javascript
|
|
221
|
+
const xhr = Ti.Network.createHTTPClient({
|
|
222
|
+
onload: () => {
|
|
223
|
+
Ti.API.info('Saved to applicationDataDirectory/test.pdf');
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
xhr.open('GET', 'http://example.com/file.pdf');
|
|
227
|
+
xhr.file = Ti.Filesystem.getFile(
|
|
228
|
+
Ti.Filesystem.applicationDataDirectory,
|
|
229
|
+
'test.pdf'
|
|
230
|
+
);
|
|
231
|
+
xhr.send();
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### File Storage Locations
|
|
235
|
+
- `applicationDataDirectory` - Primary read/write location for app files
|
|
236
|
+
- `resourcesDirectory` - Read-only app resources (writeable in simulator only)
|
|
237
|
+
- `tempDirectory` - Temporary files, OS may delete when app closes
|
|
238
|
+
- `externalCacheDirectory` - Android SD card cache (check `isExternalStoragePresent()`)
|
|
239
|
+
- `applicationCacheDirectory` - Cache data, persists but OS may clean
|
|
240
|
+
|
|
241
|
+
## 5. Sockets
|
|
242
|
+
|
|
243
|
+
Titanium supports TCP socket connections via `Ti.Network.Socket`.
|
|
244
|
+
|
|
245
|
+
### Creating a TCP Socket
|
|
246
|
+
|
|
247
|
+
```javascript
|
|
248
|
+
const socket = Ti.Network.Socket.createTCP({
|
|
249
|
+
host: 'example.com',
|
|
250
|
+
port: 80,
|
|
251
|
+
connected: function(e) {
|
|
252
|
+
Ti.API.info('Socket connected');
|
|
253
|
+
// Write data
|
|
254
|
+
this.write(Ti.createBuffer({
|
|
255
|
+
value: 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'
|
|
256
|
+
}));
|
|
257
|
+
},
|
|
258
|
+
error: (e) => {
|
|
259
|
+
Ti.API.error(`Socket error: ${e.error}`);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
socket.connect();
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Socket Listening (Android/iOS)
|
|
267
|
+
To create a socket server that accepts connections:
|
|
268
|
+
```javascript
|
|
269
|
+
const listenSocket = Ti.Network.Socket.createTCP({
|
|
270
|
+
host: '127.0.0.1', // localhost
|
|
271
|
+
port: 40404,
|
|
272
|
+
accepted: (e) => {
|
|
273
|
+
Ti.API.info(`Incoming connection accepted: ${e.inbound}`);
|
|
274
|
+
e.inbound.close();
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
listenSocket.listen();
|
|
278
|
+
listenSocket.accept(); // Asynchronous, waits for next connection
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## 6. Dealing with SOAP Web Services
|
|
282
|
+
|
|
283
|
+
Although JSON is recommended, you can consume legacy SOAP services using a "low-tech" approach by sending the XML envelope manually.
|
|
284
|
+
|
|
285
|
+
### Manual Approach (SOAP Envelope)
|
|
286
|
+
```javascript
|
|
287
|
+
const client = Ti.Network.createHTTPClient();
|
|
288
|
+
client.onload = () => {
|
|
289
|
+
const doc = client.responseXML.documentElement;
|
|
290
|
+
// Parse the response XML manually
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const soapRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n" +
|
|
294
|
+
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"> \n" +
|
|
295
|
+
"<SOAP-ENV:Body> \n" +
|
|
296
|
+
" <GetUserDetailsReq> \n" +
|
|
297
|
+
" <SessionToken>XXXX</SessionToken> \n" +
|
|
298
|
+
" </GetUserDetailsReq> \n" +
|
|
299
|
+
"</SOAP-ENV:Body> \n" +
|
|
300
|
+
"</SOAP-ENV:Envelope>";
|
|
301
|
+
|
|
302
|
+
client.open('POST', 'https://server.com/service.asmx');
|
|
303
|
+
client.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
|
|
304
|
+
client.send({ xml: soapRequest });
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## 7. SSL Certificate & Security Manager
|
|
308
|
+
|
|
309
|
+
For robust security (SSL Pinning), use the `securityManager` property.
|
|
310
|
+
|
|
311
|
+
### SSL Pinning (TiSDK 3.3.0+)
|
|
312
|
+
Unlike standard certificate validation, Pinning ensures the app only communicates with a server having a specific certificate.
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
const xhr = Ti.Network.createHTTPClient({
|
|
316
|
+
validatesSecureCertificate: true,
|
|
317
|
+
// securityManager allows implementing custom validation logic
|
|
318
|
+
securityManager: mySecurityModule
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Android: addTrustManager
|
|
323
|
+
Allows adding custom certificates for development environments or private networks:
|
|
324
|
+
```javascript
|
|
325
|
+
const certificateStore = require('ti.certificatestore');
|
|
326
|
+
const xhr = Ti.Network.createHTTPClient();
|
|
327
|
+
|
|
328
|
+
certificateStore.addCertificate('server.p12', 'password');
|
|
329
|
+
xhr.addTrustManager(certificateStore.getTrustManager());
|
|
330
|
+
|
|
331
|
+
xhr.open("GET", url);
|
|
332
|
+
xhr.send();
|
|
333
|
+
```
|
|
334
|
+
## CORS Considerations for Mobile Web
|
|
335
|
+
|
|
336
|
+
For Mobile Web targets accessing cross-domain resources:
|
|
337
|
+
- Enable CORS headers on server
|
|
338
|
+
- Or configure a proxy service
|
|
339
|
+
- Use custom `Ti.Network.httpURLFormatter`
|
|
340
|
+
|
|
341
|
+
## Best Practices
|
|
342
|
+
|
|
343
|
+
1. **Always set timeouts** to prevent hanging requests
|
|
344
|
+
2. **Handle both `onload` and `onerror`** - never assume success
|
|
345
|
+
3. **Use progress callbacks** for large file operations
|
|
346
|
+
4. **Save large downloads directly to disk** using `file` property (iOS) or `write()` to avoid memory exhaustion
|
|
347
|
+
5. **For complex JSON**, validate schema before parsing
|
|
348
|
+
6. **For XML**, always test with actual API response to verify node hierarchy
|
|
349
|
+
7. **Use `onsendstream`/`ondatastream`** to provide user feedback during transfers
|