@maccesar/titools 2.0.6 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/{AGENTS-TEMPLATE.md → AGENTS-VERCEL-RESEARCH.md} +16 -18
  2. package/README.md +250 -168
  3. package/agents/{ti-researcher.md → ti-pro.md} +10 -10
  4. package/bin/titools.js +16 -12
  5. package/lib/cleanup.js +95 -0
  6. package/lib/commands/agents.js +146 -70
  7. package/lib/commands/skills.js +349 -0
  8. package/lib/commands/uninstall.js +189 -154
  9. package/lib/commands/update.js +104 -21
  10. package/lib/config.js +26 -20
  11. package/lib/downloader.js +1 -1
  12. package/lib/installer.js +37 -97
  13. package/lib/platform.js +9 -5
  14. package/lib/prompts/checkboxCancel.js +264 -0
  15. package/lib/prompts/selectCancel.js +204 -0
  16. package/lib/symlink.js +19 -7
  17. package/lib/utils.js +21 -31
  18. package/package.json +10 -10
  19. package/skills/alloy-guides/SKILL.md +8 -30
  20. package/skills/alloy-guides/references/CLI_TASKS.md +14 -24
  21. package/skills/alloy-guides/references/CONCEPTS.md +5 -25
  22. package/skills/alloy-guides/references/CONTROLLERS.md +2 -19
  23. package/skills/alloy-guides/references/MODELS.md +40 -10
  24. package/skills/alloy-guides/references/PURGETSS.md +1 -11
  25. package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +8 -14
  26. package/skills/alloy-guides/references/VIEWS_STYLES.md +14 -25
  27. package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +2 -8
  28. package/skills/alloy-guides/references/VIEWS_XML.md +29 -40
  29. package/skills/alloy-guides/references/WIDGETS.md +1 -17
  30. package/skills/alloy-howtos/SKILL.md +1 -22
  31. package/skills/alloy-howtos/references/best_practices.md +0 -17
  32. package/skills/alloy-howtos/references/cli_reference.md +1 -23
  33. package/skills/alloy-howtos/references/config_files.md +86 -15
  34. package/skills/alloy-howtos/references/custom_tags.md +14 -13
  35. package/skills/alloy-howtos/references/debugging_troubleshooting.md +3 -22
  36. package/skills/alloy-howtos/references/samples.md +4 -14
  37. package/skills/purgetss/SKILL.md +11 -37
  38. package/skills/purgetss/references/EXAMPLES.md +106 -17
  39. package/skills/purgetss/references/animation-system.md +0 -67
  40. package/skills/purgetss/references/apply-directive.md +0 -18
  41. package/skills/purgetss/references/arbitrary-values.md +0 -25
  42. package/skills/purgetss/references/class-index.md +0 -46
  43. package/skills/purgetss/references/cli-commands.md +0 -41
  44. package/skills/purgetss/references/configurable-properties.md +0 -55
  45. package/skills/purgetss/references/custom-rules.md +0 -14
  46. package/skills/purgetss/references/customization-deep-dive.md +0 -49
  47. package/skills/purgetss/references/dynamic-component-creation.md +56 -37
  48. package/skills/purgetss/references/grid-layout.md +0 -32
  49. package/skills/purgetss/references/icon-fonts.md +0 -50
  50. package/skills/purgetss/references/installation-setup.md +61 -32
  51. package/skills/purgetss/references/migration-guide.md +127 -0
  52. package/skills/purgetss/references/opacity-modifier.md +0 -34
  53. package/skills/purgetss/references/performance-tips.md +261 -0
  54. package/skills/purgetss/references/platform-modifiers.md +0 -46
  55. package/skills/purgetss/references/smart-mappings.md +0 -12
  56. package/skills/purgetss/references/tikit-components.md +393 -0
  57. package/skills/purgetss/references/titanium-resets.md +1 -27
  58. package/skills/purgetss/references/ui-ux-design.md +467 -117
  59. package/skills/{alloy-expert → ti-expert}/SKILL.md +45 -54
  60. package/skills/ti-expert/references/alloy-builtins.md +387 -0
  61. package/skills/{alloy-expert → ti-expert}/references/alloy-structure.md +147 -40
  62. package/skills/ti-expert/references/anti-patterns.md +90 -0
  63. package/skills/ti-expert/references/cli-expert.md +109 -0
  64. package/skills/{alloy-expert → ti-expert}/references/code-conventions.md +182 -49
  65. package/skills/{alloy-expert → ti-expert}/references/controller-patterns.md +103 -93
  66. package/skills/{alloy-expert → ti-expert}/references/error-handling.md +12 -12
  67. package/skills/{alloy-expert → ti-expert}/references/examples.md +144 -85
  68. package/skills/{alloy-expert → ti-expert}/references/migration-patterns.md +38 -36
  69. package/skills/{alloy-expert → ti-expert}/references/patterns.md +8 -8
  70. package/skills/ti-expert/references/performance-listview.md +251 -0
  71. package/skills/{alloy-expert/references/performance-patterns.md → ti-expert/references/performance-optimization.md} +67 -283
  72. package/skills/{alloy-expert/references/security-patterns.md → ti-expert/references/security-device.md} +12 -295
  73. package/skills/ti-expert/references/security-fundamentals.md +284 -0
  74. package/skills/{alloy-expert → ti-expert}/references/state-management.md +10 -10
  75. package/skills/ti-expert/references/testing-e2e-ci.md +432 -0
  76. package/skills/ti-expert/references/testing-unit.md +433 -0
  77. package/skills/ti-expert/references/theming.md +394 -0
  78. package/skills/ti-guides/SKILL.md +1 -14
  79. package/skills/ti-guides/references/advanced-data-and-images.md +126 -10
  80. package/skills/ti-guides/references/app-distribution.md +48 -10
  81. package/skills/ti-guides/references/application-frameworks.md +9 -2
  82. package/skills/ti-guides/references/cli-reference.md +338 -82
  83. package/skills/ti-guides/references/coding-best-practices.md +14 -4
  84. package/skills/ti-guides/references/commonjs-advanced.md +103 -6
  85. package/skills/ti-guides/references/hello-world.md +5 -2
  86. package/skills/ti-guides/references/hyperloop-native-access.md +439 -46
  87. package/skills/ti-guides/references/javascript-primer.md +4 -3
  88. package/skills/ti-guides/references/resources.md +0 -1
  89. package/skills/ti-guides/references/style-and-conventions.md +57 -9
  90. package/skills/ti-guides/references/tiapp-config.md +48 -6
  91. package/skills/ti-howtos/SKILL.md +2 -27
  92. package/skills/ti-howtos/references/android-platform-deep-dives.md +41 -90
  93. package/skills/ti-howtos/references/automation-fastlane-appium.md +15 -14
  94. package/skills/ti-howtos/references/buffer-codec-streams.md +22 -22
  95. package/skills/ti-howtos/references/cross-platform-development.md +68 -37
  96. package/skills/ti-howtos/references/debugging-profiling.md +8 -53
  97. package/skills/ti-howtos/references/extending-titanium.md +12 -51
  98. package/skills/ti-howtos/references/google-maps-v2.md +30 -29
  99. package/skills/ti-howtos/references/ios-map-kit.md +19 -25
  100. package/skills/ti-howtos/references/ios-platform-deep-dives.md +95 -283
  101. package/skills/ti-howtos/references/local-data-sources.md +45 -37
  102. package/skills/ti-howtos/references/location-and-maps.md +47 -28
  103. package/skills/ti-howtos/references/media-apis.md +84 -27
  104. package/skills/ti-howtos/references/notification-services.md +40 -89
  105. package/skills/ti-howtos/references/remote-data-sources.md +21 -36
  106. package/skills/ti-howtos/references/tutorials.md +79 -39
  107. package/skills/ti-howtos/references/using-modules.md +4 -30
  108. package/skills/ti-howtos/references/web-content-integration.md +28 -45
  109. package/skills/ti-howtos/references/webpack-build-pipeline.md +54 -18
  110. package/skills/ti-ui/SKILL.md +1 -21
  111. package/skills/ti-ui/references/accessibility-deep-dive.md +71 -25
  112. package/skills/ti-ui/references/animation-and-matrices.md +0 -47
  113. package/skills/ti-ui/references/application-structures.md +0 -46
  114. package/skills/ti-ui/references/custom-fonts-styling.md +9 -57
  115. package/skills/ti-ui/references/event-handling.md +32 -40
  116. package/skills/ti-ui/references/gestures.md +0 -40
  117. package/skills/ti-ui/references/icons-and-splash-screens.md +21 -44
  118. package/skills/ti-ui/references/layouts-and-positioning.md +47 -39
  119. package/skills/ti-ui/references/listviews-and-performance.md +187 -73
  120. package/skills/ti-ui/references/orientation.md +57 -71
  121. package/skills/ti-ui/references/platform-ui-android.md +114 -48
  122. package/skills/ti-ui/references/platform-ui-ios.md +63 -38
  123. package/skills/ti-ui/references/scrolling-views.md +14 -23
  124. package/skills/ti-ui/references/tableviews.md +6 -56
  125. package/lib/commands/install.js +0 -188
  126. package/skills/alloy-expert/references/anti-patterns.md +0 -133
  127. package/skills/alloy-expert/references/testing.md +0 -872
  128. package/skills/ti-guides/references/alloy-cli-advanced.md +0 -84
  129. package/skills/ti-guides/references/alloy-data-mastery.md +0 -29
  130. package/skills/ti-guides/references/alloy-widgets-and-themes.md +0 -19
  131. /package/skills/{alloy-expert → ti-expert}/assets/ControllerAutoCleanup.js +0 -0
  132. /package/skills/{alloy-expert → ti-expert}/references/contracts.md +0 -0
@@ -1,32 +1,5 @@
1
1
  # Media APIs
2
2
 
3
- ## Table of Contents
4
-
5
- - [Media APIs](#media-apis)
6
- - [Table of Contents](#table-of-contents)
7
- - [1. Audio APIs](#1-audio-apis)
8
- - [Playing Basic Sounds (Ti.Media.Sound)](#playing-basic-sounds-timediasound)
9
- - [Streaming Audio (Ti.Media.AudioPlayer)](#streaming-audio-timediaaudioplayer)
10
- - [Recording Audio (Ti.Media.AudioRecorder)](#recording-audio-timediaaudiorecorder)
11
- - [2. Video APIs (Ti.Media.VideoPlayer)](#2-video-apis-timediavideoplayer)
12
- - [Cross-Platform Considerations](#cross-platform-considerations)
13
- - [Basic Usage](#basic-usage)
14
- - [Key Events](#key-events)
15
- - [3. Camera and Photo Gallery APIs](#3-camera-and-photo-gallery-apis)
16
- - [Camera (Ti.Media.showCamera)](#camera-timediashowcamera)
17
- - [Gallery (Ti.Media.openPhotoGallery)](#gallery-timediaopenphotogallery)
18
- - [Memory Management](#memory-management)
19
- - [4. Images and ImageView APIs](#4-images-and-imageview-apis)
20
- - [Background Images](#background-images)
21
- - [ImageView Component](#imageview-component)
22
- - [Density-Specific Images](#density-specific-images)
23
- - [Flipbook Animations](#flipbook-animations)
24
- - [Permissions Checklist](#permissions-checklist)
25
- - [iOS (tiapp.xml)](#ios-tiappxml)
26
- - [Android (tiapp.xml)](#android-tiappxml)
27
-
28
- ---
29
-
30
3
  ## 1. Audio APIs
31
4
 
32
5
  ### Playing Basic Sounds (Ti.Media.Sound)
@@ -77,6 +50,13 @@ Ti.App.addEventListener('resume', () => { streamer.setPaused(false); });
77
50
  - `movieControlStyle`: `Ti.Media.VIDEO_CONTROL_EMBEDDED` for embedded controls
78
51
  - `scalingMode`: Control fill/fit behavior
79
52
 
53
+ ```javascript
54
+ const videoPlayer = Ti.Media.createVideoPlayer({
55
+ url: 'movie.mp4',
56
+ scalingMode: Ti.Media.VIDEO_SCALING_ASPECT_FIT // or ASPECT_FILL, MODE_FILL, NONE
57
+ });
58
+ ```
59
+
80
60
  ```javascript
81
61
  const player = Ti.Media.createVideoPlayer({
82
62
  url: 'movie.mp4',
@@ -100,16 +80,87 @@ win.addEventListener('close', () => { player.stop(); });
100
80
 
101
81
  ## 3. Camera and Photo Gallery APIs
102
82
 
83
+ ### Camera Availability and Permissions
84
+
85
+ Always check device support and permissions before opening the camera:
86
+
87
+ ```javascript
88
+ if (!Ti.Media.isCameraSupported) {
89
+ Ti.API.warn('No camera available on this device');
90
+ return;
91
+ }
92
+
93
+ if (Ti.Media.hasCameraPermissions()) {
94
+ openCamera();
95
+ } else {
96
+ Ti.Media.requestCameraPermissions((e) => {
97
+ if (e.success) {
98
+ openCamera();
99
+ } else {
100
+ Ti.API.error('Camera permission denied');
101
+ }
102
+ });
103
+ }
104
+ ```
105
+
106
+ **Required tiapp.xml keys (iOS)**:
107
+ ```xml
108
+ <key>NSCameraUsageDescription</key>
109
+ <string>We need camera access to take photos</string>
110
+ <key>NSPhotoLibraryUsageDescription</key>
111
+ <string>We need photo library access to save photos</string>
112
+ ```
113
+
103
114
  ### Camera (Ti.Media.showCamera)
104
115
  - Requires camera permission and usage descriptions
105
116
  - Success callback provides `event.media` (blob)
106
117
  - Use `saveToPhotoGallery: true` to automatically save
107
118
  - Handle `cancel` and `error` callbacks
108
119
 
120
+ ### Front and Rear Camera
121
+ ```javascript
122
+ const cameras = Ti.Media.availableCameras;
123
+
124
+ // Check if front camera exists
125
+ if (cameras.indexOf(Ti.Media.CAMERA_FRONT) !== -1) {
126
+ Ti.Media.showCamera({
127
+ whichCamera: Ti.Media.CAMERA_FRONT,
128
+ // ... other options
129
+ });
130
+ }
131
+
132
+ // Switch camera programmatically
133
+ Ti.Media.switchCamera(Ti.Media.CAMERA_REAR);
134
+ ```
135
+
136
+ ### Advanced Camera Options (iOS)
137
+ | Property | Description |
138
+ |---|---|
139
+ | `autohide` | Auto-hide camera after capture (default: true) |
140
+ | `animated` | Animate camera appearance |
141
+ | `allowEditing` | Allow user to crop/edit after capture |
142
+ | `mediaTypes` | Array: `MEDIA_TYPE_PHOTO`, `MEDIA_TYPE_VIDEO` |
143
+ | `videoMaximumDuration` | Max video duration in milliseconds |
144
+ | `videoQuality` | `QUALITY_HIGH`, `QUALITY_MEDIUM`, `QUALITY_LOW` |
145
+ | `overlay` | Custom Ti.UI.View overlay on camera |
146
+ | `showControls` | Show/hide default camera controls |
147
+
148
+ When using a custom overlay, call `Ti.Media.takePicture()` to capture and `Ti.Media.hideCamera()` to dismiss.
149
+
109
150
  ### Gallery (Ti.Media.openPhotoGallery)
110
151
  - Success callback provides `event.media` (blob)
111
152
  - Note: `event.media` may contain only file info, use `Ti.Filesystem.getFile(event.media.nativePath)` to access actual file
112
153
 
154
+ ### iPad-Specific Gallery Options
155
+ On iPad, the photo gallery opens as a popover. Configure its position:
156
+ ```javascript
157
+ Ti.Media.openPhotoGallery({
158
+ popoverView: myButton, // Anchor popover to this view
159
+ arrowDirection: Ti.UI.iPad.POPOVER_ARROW_DIRECTION_UP,
160
+ success: (e) => { /* ... */ }
161
+ });
162
+ ```
163
+
113
164
  ### Memory Management
114
165
  - **Critical**: Use `imageAsResized()` on blobs to avoid memory exhaustion
115
166
  - For display: Resize to target dimensions before assigning to ImageView
@@ -132,6 +183,12 @@ Ti.Media.showCamera({
132
183
  - **iOS**: Use `backgroundLeftCap` and `backgroundTopCap` to control stretch regions
133
184
  - **Android**: Supports remote URLs as background images; iOS does not
134
185
 
186
+ ### Image Stretching (Background Images)
187
+ When using small images as backgrounds, iOS and Android stretch differently:
188
+ - **`backgroundLeftCap`** (iOS): Number of pixels from the left that are NOT stretched. The middle section stretches.
189
+ - **`backgroundTopCap`** (iOS): Number of pixels from the top that are NOT stretched.
190
+ - **Android**: Supports remote URLs for background images; iOS does NOT.
191
+
135
192
  ### ImageView Component
136
193
  - `image` property accepts: URL, local path, or Ti.Filesystem.File object
137
194
  - Scaling behavior:
@@ -2,53 +2,6 @@
2
2
 
3
3
  Comprehensive guide for local and push notifications on iOS and Android.
4
4
 
5
- ## Table of Contents
6
-
7
- - [Push and Local Notifications](#push-and-local-notifications)
8
- - [Table of Contents](#table-of-contents)
9
- - [Local Notifications Android](#local-notifications-android)
10
- - [Notification Display Locations](#notification-display-locations)
11
- - [Create a Notification](#create-a-notification)
12
- - [Sound](#sound)
13
- - [Custom Layout with RemoteViews](#custom-layout-with-remoteviews)
14
- - [Additional Properties](#additional-properties)
15
- - [Update Notification](#update-notification)
16
- - [Remove Notifications](#remove-notifications)
17
- - [Respond to Notification Tap](#respond-to-notification-tap)
18
- - [Schedule Future Notification (Background Service)](#schedule-future-notification-background-service)
19
- - [Local Notifications iOS](#local-notifications-ios)
20
- - [Notification Display Locations](#notification-display-locations-1)
21
- - [Register for Notifications (iOS 8+)](#register-for-notifications-ios-8)
22
- - [Schedule Local Notification](#schedule-local-notification)
23
- - [Monitor Notifications](#monitor-notifications)
24
- - [Cancel Notifications](#cancel-notifications)
25
- - [Interactive Notifications iOS (iOS 8+)](#interactive-notifications-ios-ios-8)
26
- - [Create Notification Actions](#create-notification-actions)
27
- - [Create Notification Category](#create-notification-category)
28
- - [Register Categories](#register-categories)
29
- - [Monitor Interactive Notifications](#monitor-interactive-notifications)
30
- - [Schedule Interactive Local Notification](#schedule-interactive-local-notification)
31
- - [Send Interactive Push Notification](#send-interactive-push-notification)
32
- - [Push Notifications](#push-notifications)
33
- - [Overview](#overview)
34
- - [Register for Push Notifications](#register-for-push-notifications)
35
- - [Configure Push Services](#configure-push-services)
36
- - [Push Notification Payload Format](#push-notification-payload-format)
37
- - [Subscribe to Channels](#subscribe-to-channels)
38
- - [Send Push Notifications](#send-push-notifications)
39
- - [Best Practices](#best-practices)
40
- - [Common Patterns](#common-patterns)
41
- - [Check Notification Permissions](#check-notification-permissions)
42
- - [PendingIntent for Notification Actions](#pendingintent-for-notification-actions)
43
- - [Notification Groups (Android 7.0+)](#notification-groups-android-70)
44
- - [Rich Notifications (iOS 10+)](#rich-notifications-ios-10)
45
- - [Silent Push](#silent-push)
46
- - [Platform-Specific Notes](#platform-specific-notes)
47
- - [Android](#android)
48
- - [iOS](#ios)
49
-
50
- ---
51
-
52
5
  ## Local Notifications Android
53
6
 
54
7
  ### Notification Display Locations
@@ -197,6 +150,17 @@ intent.addCategory(Ti.Android.CATEGORY_LAUNCHER);
197
150
  notification.contentIntent = Ti.Android.createPendingIntent({intent: intent});
198
151
  ```
199
152
 
153
+ ### Delete Intent (Notification Cleared)
154
+
155
+ ```javascript
156
+ // Execute intent when user clears notification
157
+ notification.deleteIntent = Ti.Android.createPendingIntent({
158
+ intent: Ti.Android.createIntent({
159
+ action: 'com.myapp.NOTIFICATION_CLEARED'
160
+ })
161
+ });
162
+ ```
163
+
200
164
  ### Schedule Future Notification (Background Service)
201
165
 
202
166
  **tiapp.xml:**
@@ -267,6 +231,13 @@ if (Ti.Platform.name === 'iPhone OS' && parseInt(Ti.Platform.version.split('.')[
267
231
  }
268
232
  ```
269
233
 
234
+ **Note**: iOS will show a system prompt asking the user to allow notifications on the first call. Check current settings with:
235
+ ```javascript
236
+ Ti.App.iOS.addEventListener('usernotificationsettings', (e) => {
237
+ Ti.API.info(`Notification types allowed: ${e.types}`);
238
+ });
239
+ ```
240
+
270
241
  ### Schedule Local Notification
271
242
 
272
243
  ```javascript
@@ -439,9 +410,15 @@ Ti.App.iOS.scheduleLocalNotification({
439
410
 
440
411
  Push notifications allow server-to-device communication. Infrastructure differs by platform:
441
412
 
442
- - **Android**: Firebase Cloud Messaging (FCM) or Google Cloud Messaging (GCM)
413
+ - **Android**: Firebase Cloud Messaging (FCM)
443
414
  - **iOS**: Apple Push Notification service (APNs)
444
415
 
416
+ > **Note**: The legacy Appcelerator Cloud Services (ACS/ArrowDB) push backend is no longer available. Use Firebase Cloud Messaging (FCM) for Android and Apple Push Notification service (APNs) for iOS, either directly or through a third-party service.
417
+
418
+ > Google has deprecated Google Cloud Messaging (GCM) in favor of Firebase Cloud Messaging (FCM). All new implementations should use FCM.
419
+
420
+ For FCM on Titanium, use the community Firebase Cloud Messaging module: `titanium-firebase-cloud-messaging` (by Hans Knöchel).
421
+
445
422
  ### Register for Push Notifications
446
423
 
447
424
  ```javascript
@@ -463,18 +440,21 @@ Ti.Network.registerForPushNotifications({
463
440
  });
464
441
  ```
465
442
 
466
- ### Configure Push Services
443
+ ### APNs Configuration (iOS)
444
+
445
+ 1. Register an **Explicit App ID** (not Wildcard) with Push Notifications enabled in Apple Developer Portal
446
+ 2. Generate an APNs certificate (Development for sandbox, Production for App Store)
447
+ 3. Export the certificate as PKCS#12 (.p12) from Keychain Access
448
+ 4. Upload the .p12 to your push service provider
449
+ 5. In your app, call `Ti.Network.registerForPushNotifications()` to get the device token
467
450
 
468
- **Android (FCM/GCM):**
469
- 1. Create project in Firebase Console or Google API Console
470
- 2. Get API key/Sender ID
471
- 3. Configure with your push provider (e.g., ArrowDB, ACS, or custom server)
451
+ ### FCM Configuration (Android)
472
452
 
473
- **iOS (APNs):**
474
- 1. Create App ID in Apple Developer Portal
475
- 2. Enable Push Notifications
476
- 3. Create SSL certificate (development/production)
477
- 4. Configure with your push provider
453
+ 1. Create a project in Firebase Console
454
+ 2. Add your Android app (use your app's package name)
455
+ 3. Download `google-services.json` and place in project root
456
+ 4. Add the `titanium-firebase-cloud-messaging` module to tiapp.xml
457
+ 5. Register for push and obtain the FCM token
478
458
 
479
459
  ### Push Notification Payload Format
480
460
 
@@ -499,38 +479,9 @@ Ti.Network.registerForPushNotifications({
499
479
  }
500
480
  ```
501
481
 
502
- ### Subscribe to Channels
503
-
504
- **Using Arrow/ACS:**
505
- ```javascript
506
- Cloud.PushNotifications.subscribeToken({
507
- device_token: deviceToken,
508
- channel: 'news',
509
- type: Ti.Platform.name === 'iPhone OS' ? 'ios' : 'android'
510
- }, (e) => {
511
- if (e.success) {
512
- Ti.API.info('Subscribed to news channel');
513
- }
514
- });
515
- ```
516
-
517
482
  ### Send Push Notifications
518
483
 
519
- **Using Arrow/ACS:**
520
- ```javascript
521
- Cloud.PushNotifications.notify({
522
- channel: 'news',
523
- payload: 'Hello subscribers!',
524
- title: 'News Update'
525
- }, (e) => {
526
- if (e.success) {
527
- Ti.API.info('Push sent successfully');
528
- }
529
- });
530
- ```
531
-
532
- **Direct API call:**
533
- Send to your push server with device tokens and payload.
484
+ Send push notifications from your server using the FCM HTTP API or APNs. Collect device tokens from client registration and target them with your push payload.
534
485
 
535
486
  ### Best Practices
536
487
 
@@ -588,7 +539,7 @@ Use `UNMutableNotificationContent` with attachments (images, video, audio).
588
539
 
589
540
  ### Android
590
541
 
591
- - **Service lifecycle**: Services may be killed if app is swiped away
542
+ - **Service lifecycle**: Services may be killed if app is swiped away. **Warning**: Android services may stop if the app is killed (user backs out or removes from recent apps). For critical notifications, use FCM push notifications instead of local services
592
543
  - **Notification channels**: Android 8.0+ requires notification channels
593
544
  - **Limitations**: Legacy MapView only supports single map view
594
545
 
@@ -1,40 +1,5 @@
1
1
  # Remote Data Sources
2
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
3
  ## 1. HTTPClient and Request Lifecycle
39
4
 
40
5
  ### Basic Pattern
@@ -195,6 +160,8 @@ if (file.exists()) {
195
160
  }
196
161
  ```
197
162
 
163
+ > **Note**: When uploading from the photo gallery, `event.media` returns a Blob. For file uploads from the filesystem, use `Ti.Filesystem.getFile(path).read()` to get the Blob.
164
+
198
165
  ### File Download (Cross-Platform)
199
166
 
200
167
  **Option 1**: Write manually to filesystem
@@ -217,6 +184,11 @@ xhr.send();
217
184
 
218
185
  **Option 2**: iOS-only automatic saving with `file` property
219
186
 
187
+ **iOS-only**: Use `xhr.file` to save downloads directly to a file without buffering in memory:
188
+ ```javascript
189
+ xhr.file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'download.zip');
190
+ ```
191
+
220
192
  ```javascript
221
193
  const xhr = Ti.Network.createHTTPClient({
222
194
  onload: () => {
@@ -278,6 +250,8 @@ listenSocket.listen();
278
250
  listenSocket.accept(); // Asynchronous, waits for next connection
279
251
  ```
280
252
 
253
+ > **Platform Note**: On iOS, `Ti.Platform.address` returns the WiFi interface address. On Android, only the loopback address (`127.0.0.1`) is available for listening sockets.
254
+
281
255
  ## 6. Dealing with SOAP Web Services
282
256
 
283
257
  Although JSON is recommended, you can consume legacy SOAP services using a "low-tech" approach by sending the XML envelope manually.
@@ -315,7 +289,18 @@ Unlike standard certificate validation, Pinning ensures the app only communicate
315
289
  const xhr = Ti.Network.createHTTPClient({
316
290
  validatesSecureCertificate: true,
317
291
  // securityManager allows implementing custom validation logic
318
- securityManager: mySecurityModule
292
+ securityManager: mySecurityModule
293
+ });
294
+ ```
295
+
296
+ ### SSL Certificate Store (Android)
297
+ ```javascript
298
+ const certificateStore = require('ti.certificatestore');
299
+ const httpClient = Ti.Network.createHTTPClient({
300
+ securityManager: certificateStore.createX509CertificatePinningSecurityManager([{
301
+ url: 'https://api.example.com',
302
+ serverCertificate: 'api_cert.der'
303
+ }])
319
304
  });
320
305
  ```
321
306
 
@@ -2,44 +2,6 @@
2
2
 
3
3
  Practical tutorials and guides for building real-world Titanium applications.
4
4
 
5
- ## Table of Contents
6
-
7
- - [Titanium SDK Tutorials](#titanium-sdk-tutorials)
8
- - [Table of Contents](#table-of-contents)
9
- - [RESTe - API Integration](#reste---api-integration)
10
- - [Overview](#overview)
11
- - [Installation](#installation)
12
- - [Basic Configuration](#basic-configuration)
13
- - [Usage](#usage)
14
- - [Backbone.js Models/Collections](#backbonejs-modelscollections)
15
- - [Important Notes](#important-notes)
16
- - [Mock Data (On-The-Fly)](#mock-data-on-the-fly)
17
- - [Resources](#resources)
18
- - [Camera App Tutorial](#camera-app-tutorial)
19
- - [Basic Camera Access](#basic-camera-access)
20
- - [Photo Gallery](#photo-gallery)
21
- - [Saving Images](#saving-images)
22
- - [Geolocation Tutorial](#geolocation-tutorial)
23
- - [Basic Location](#basic-location)
24
- - [Continuous Tracking](#continuous-tracking)
25
- - [Reverse Geocoding](#reverse-geocoding)
26
- - [Alloy Controller Chaining](#alloy-controller-chaining)
27
- - [Pattern Overview](#pattern-overview)
28
- - [Basic Pattern](#basic-pattern)
29
- - [Benefits](#benefits)
30
- - [Build Automation with Fastlane](#build-automation-with-fastlane)
31
- - [Overview](#overview-1)
32
- - [Installing Fastlane](#installing-fastlane)
33
- - [Basic Fastfile](#basic-fastfile)
34
- - [Usage](#usage-1)
35
- - [Advanced Options](#advanced-options)
36
- - [Additional Tutorials](#additional-tutorials)
37
- - [Alloy Boilerplates](#alloy-boilerplates)
38
- - [Complete Sample Apps](#complete-sample-apps)
39
- - [Resources](#resources-1)
40
-
41
- ---
42
-
43
5
  ## RESTe - API Integration
44
6
 
45
7
  ### Overview
@@ -67,7 +29,7 @@ const api = new reste();
67
29
 
68
30
  api.config({
69
31
  debug: true, // Console logging
70
- errorsAsObjects: true, // Return errors as objects (1.4.5+)
32
+ errorsAsObjects: true, // Return errors as objects (1.4.5+) — WARNING: breaks apps written for 1.4.4 that handle errors differently
71
33
  autoValidateParams: false, // Throw error if params missing
72
34
  validatesSecureCertificate: false,
73
35
  timeout: 4000,
@@ -169,6 +131,19 @@ Alloy.Collections.videos.fetch({
169
131
  </TableView>
170
132
  ```
171
133
 
134
+ ### RESTe Advanced Features
135
+
136
+ - **Caching**: Built-in response caching support
137
+ - **Promises**: Use with `q.js` for Promise-based API calls
138
+ - **Mock data**: Create models/collections on-the-fly for testing:
139
+ ```javascript
140
+ const mockUser = api.createModel('users', {
141
+ id: 1,
142
+ name: 'Test User'
143
+ });
144
+ ```
145
+ - **Backbone.js binding**: Use RESTe models directly with Alloy data binding without `<Model>` tags
146
+
172
147
  ### Important Notes
173
148
 
174
149
  - **Don't use `<Model>` or `<Collection>` tags** with RESTe
@@ -201,6 +176,29 @@ const videoCollection = api.createCollection('videos', [
201
176
 
202
177
  ## Camera App Tutorial
203
178
 
179
+ ### Camera Permissions Setup
180
+
181
+ **iOS** — add to tiapp.xml plist:
182
+ ```xml
183
+ <key>NSCameraUsageDescription</key>
184
+ <string>This app needs camera access to take photos</string>
185
+ <key>NSMicrophoneUsageDescription</key>
186
+ <string>This app needs microphone access for video recording</string>
187
+ ```
188
+
189
+ **Android**: Camera permissions are automatically added by the build system when using `Ti.Media.showCamera()`.
190
+
191
+ Always check permissions at runtime:
192
+ ```javascript
193
+ if (!Ti.Media.hasCameraPermissions()) {
194
+ Ti.Media.requestCameraPermissions((e) => {
195
+ if (e.success) openCamera();
196
+ });
197
+ } else {
198
+ openCamera();
199
+ }
200
+ ```
201
+
204
202
  ### Basic Camera Access
205
203
 
206
204
  ```javascript
@@ -275,6 +273,31 @@ Ti.Media.saveToPhotoGallery({
275
273
 
276
274
  ## Geolocation Tutorial
277
275
 
276
+ ### Geolocation Permissions Setup
277
+
278
+ **iOS** — add to tiapp.xml plist:
279
+ ```xml
280
+ <key>NSLocationWhenInUseUsageDescription</key>
281
+ <string>We need your location to show nearby places</string>
282
+ <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
283
+ <string>We need your location for background tracking</string>
284
+ ```
285
+
286
+ **Android** — add to tiapp.xml manifest:
287
+ ```xml
288
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
289
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
290
+ ```
291
+
292
+ Runtime permission check:
293
+ ```javascript
294
+ if (!Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE)) {
295
+ Ti.Geolocation.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE, (e) => {
296
+ if (e.success) startTracking();
297
+ });
298
+ }
299
+ ```
300
+
278
301
  ### Basic Location
279
302
 
280
303
  ```javascript
@@ -321,6 +344,23 @@ Ti.Geolocation.reverseGeocoder(37.389569, -122.050212, (e) => {
321
344
  });
322
345
  ```
323
346
 
347
+ ### Accuracy Tuning
348
+
349
+ ```javascript
350
+ // iOS: minimum distance before firing event
351
+ Ti.Geolocation.distanceFilter = 10; // meters
352
+
353
+ // Android: use FusedLocationProvider for better battery (requires ti.playservices module)
354
+ // Automatically enabled with SDK 7.1.0+ when ti.playservices is present
355
+
356
+ // Android: custom location rules
357
+ Ti.Geolocation.Android.addLocationRule(Ti.Geolocation.Android.createLocationRule({
358
+ provider: Ti.Geolocation.Android.PROVIDER_GPS,
359
+ accuracy: 100, // meters
360
+ minAge: 1000 // milliseconds
361
+ }));
362
+ ```
363
+
324
364
  ---
325
365
 
326
366
  ## Alloy Controller Chaining
@@ -2,34 +2,6 @@
2
2
 
3
3
  Guide for obtaining, installing, and using Titanium modules to extend app functionality.
4
4
 
5
- ## Table of Contents
6
-
7
- - [Using Modules](#using-modules)
8
- - [Table of Contents](#table-of-contents)
9
- - [Obtaining Modules](#obtaining-modules)
10
- - [Sources of Modules](#sources-of-modules)
11
- - [Installing Modules](#installing-modules)
12
- - [Single Project Installation](#single-project-installation)
13
- - [Global Installation (All Projects)](#global-installation-all-projects)
14
- - [Configuring Your App](#configuring-your-app)
15
- - [Updating tiapp.xml](#updating-tiappxml)
16
- - [Selecting Module Versions](#selecting-module-versions)
17
- - [Enable Debugger (for native modules)](#enable-debugger-for-native-modules)
18
- - [Using a Module](#using-a-module)
19
- - [Loading the Module (ES5)](#loading-the-module-es5)
20
- - [Loading the Module (ES6+)](#loading-the-module-es6)
21
- - [Using Module Functionality](#using-module-functionality)
22
- - [Module Patterns](#module-patterns)
23
- - [Troubleshooting](#troubleshooting)
24
- - ["Requested module not found"](#requested-module-not-found)
25
- - [Version Conflicts](#version-conflicts)
26
- - [Platform-Specific Issues](#platform-specific-issues)
27
- - [Clean Build](#clean-build)
28
- - [Best Practices](#best-practices)
29
- - [Module Development](#module-development)
30
-
31
- ---
32
-
33
5
  ## Obtaining Modules
34
6
 
35
7
  ### Sources of Modules
@@ -55,8 +27,10 @@ Guide for obtaining, installing, and using Titanium modules to extend app functi
55
27
  - Curated list of modules maintained by Michael Gangolf
56
28
 
57
29
  **Marketplace:**
58
- - Appcelerator Marketplace is no longer in use
59
- - Contact marketplace-admin@axway.com for previously purchased modules
30
+ > **Note**: The original Appcelerator Marketplace is no longer available. Find community modules on GitHub and npm. A curated list is at [From Zero to App](https://fromzerotoapp.com/modules/).
31
+
32
+ ### Pre-installed Modules
33
+ Some modules ship with the SDK and don't need separate installation: `ti.map`, `ti.identity`, `ti.webdialog`, `ti.applesignin`
60
34
 
61
35
  ---
62
36