@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.
Files changed (120) hide show
  1. package/AGENTS-TEMPLATE.md +173 -0
  2. package/README.md +867 -0
  3. package/agents/ti-researcher.md +108 -0
  4. package/bin/titools.js +53 -0
  5. package/lib/commands/agents.js +126 -0
  6. package/lib/commands/install.js +188 -0
  7. package/lib/commands/uninstall.js +215 -0
  8. package/lib/commands/update.js +159 -0
  9. package/lib/config.js +119 -0
  10. package/lib/downloader.js +153 -0
  11. package/lib/installer.js +253 -0
  12. package/lib/platform.js +108 -0
  13. package/lib/symlink.js +142 -0
  14. package/lib/utils.js +270 -0
  15. package/package.json +67 -0
  16. package/skills/alloy-expert/SKILL.md +247 -0
  17. package/skills/alloy-expert/assets/ControllerAutoCleanup.js +182 -0
  18. package/skills/alloy-expert/references/alloy-structure.md +381 -0
  19. package/skills/alloy-expert/references/anti-patterns.md +133 -0
  20. package/skills/alloy-expert/references/code-conventions.md +469 -0
  21. package/skills/alloy-expert/references/contracts.md +280 -0
  22. package/skills/alloy-expert/references/controller-patterns.md +520 -0
  23. package/skills/alloy-expert/references/error-handling.md +484 -0
  24. package/skills/alloy-expert/references/examples.md +735 -0
  25. package/skills/alloy-expert/references/migration-patterns.md +298 -0
  26. package/skills/alloy-expert/references/patterns.md +448 -0
  27. package/skills/alloy-expert/references/performance-patterns.md +855 -0
  28. package/skills/alloy-expert/references/security-patterns.md +847 -0
  29. package/skills/alloy-expert/references/state-management.md +779 -0
  30. package/skills/alloy-expert/references/testing.md +872 -0
  31. package/skills/alloy-guides/SKILL.md +214 -0
  32. package/skills/alloy-guides/references/CLI_TASKS.md +243 -0
  33. package/skills/alloy-guides/references/CONCEPTS.md +191 -0
  34. package/skills/alloy-guides/references/CONTROLLERS.md +298 -0
  35. package/skills/alloy-guides/references/MODELS.md +1028 -0
  36. package/skills/alloy-guides/references/PURGETSS.md +56 -0
  37. package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +242 -0
  38. package/skills/alloy-guides/references/VIEWS_STYLES.md +388 -0
  39. package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +109 -0
  40. package/skills/alloy-guides/references/VIEWS_XML.md +558 -0
  41. package/skills/alloy-guides/references/WIDGETS.md +176 -0
  42. package/skills/alloy-howtos/SKILL.md +203 -0
  43. package/skills/alloy-howtos/references/best_practices.md +138 -0
  44. package/skills/alloy-howtos/references/cli_reference.md +253 -0
  45. package/skills/alloy-howtos/references/config_files.md +87 -0
  46. package/skills/alloy-howtos/references/custom_tags.md +147 -0
  47. package/skills/alloy-howtos/references/debugging_troubleshooting.md +101 -0
  48. package/skills/alloy-howtos/references/samples.md +167 -0
  49. package/skills/purgetss/SKILL.md +442 -0
  50. package/skills/purgetss/assets/purgetss.config.cjs +17 -0
  51. package/skills/purgetss/references/EXAMPLES.md +247 -0
  52. package/skills/purgetss/references/animation-system.md +1294 -0
  53. package/skills/purgetss/references/apply-directive.md +375 -0
  54. package/skills/purgetss/references/arbitrary-values.md +612 -0
  55. package/skills/purgetss/references/class-index.md +1350 -0
  56. package/skills/purgetss/references/cli-commands.md +948 -0
  57. package/skills/purgetss/references/configurable-properties.md +654 -0
  58. package/skills/purgetss/references/custom-rules.md +161 -0
  59. package/skills/purgetss/references/customization-deep-dive.md +722 -0
  60. package/skills/purgetss/references/dynamic-component-creation.md +489 -0
  61. package/skills/purgetss/references/grid-layout.md +455 -0
  62. package/skills/purgetss/references/icon-fonts.md +609 -0
  63. package/skills/purgetss/references/installation-setup.md +366 -0
  64. package/skills/purgetss/references/opacity-modifier.md +291 -0
  65. package/skills/purgetss/references/platform-modifiers.md +479 -0
  66. package/skills/purgetss/references/smart-mappings.md +42 -0
  67. package/skills/purgetss/references/titanium-resets.md +359 -0
  68. package/skills/purgetss/references/ui-ux-design.md +1526 -0
  69. package/skills/ti-guides/SKILL.md +94 -0
  70. package/skills/ti-guides/references/advanced-data-and-images.md +19 -0
  71. package/skills/ti-guides/references/alloy-cli-advanced.md +84 -0
  72. package/skills/ti-guides/references/alloy-data-mastery.md +29 -0
  73. package/skills/ti-guides/references/alloy-widgets-and-themes.md +19 -0
  74. package/skills/ti-guides/references/android-manifest.md +97 -0
  75. package/skills/ti-guides/references/app-distribution.md +258 -0
  76. package/skills/ti-guides/references/application-frameworks.md +377 -0
  77. package/skills/ti-guides/references/cli-reference.md +402 -0
  78. package/skills/ti-guides/references/coding-best-practices.md +102 -0
  79. package/skills/ti-guides/references/commonjs-advanced.md +134 -0
  80. package/skills/ti-guides/references/hello-world.md +100 -0
  81. package/skills/ti-guides/references/hyperloop-native-access.md +62 -0
  82. package/skills/ti-guides/references/javascript-primer.md +411 -0
  83. package/skills/ti-guides/references/reserved-words.md +36 -0
  84. package/skills/ti-guides/references/resources.md +183 -0
  85. package/skills/ti-guides/references/style-and-conventions.md +48 -0
  86. package/skills/ti-guides/references/tiapp-config.md +609 -0
  87. package/skills/ti-howtos/SKILL.md +174 -0
  88. package/skills/ti-howtos/references/android-platform-deep-dives.md +658 -0
  89. package/skills/ti-howtos/references/automation-fastlane-appium.md +95 -0
  90. package/skills/ti-howtos/references/buffer-codec-streams.md +140 -0
  91. package/skills/ti-howtos/references/cross-platform-development.md +348 -0
  92. package/skills/ti-howtos/references/debugging-profiling.md +543 -0
  93. package/skills/ti-howtos/references/extending-titanium.md +723 -0
  94. package/skills/ti-howtos/references/google-maps-v2.md +169 -0
  95. package/skills/ti-howtos/references/ios-map-kit.md +143 -0
  96. package/skills/ti-howtos/references/ios-platform-deep-dives.md +783 -0
  97. package/skills/ti-howtos/references/local-data-sources.md +301 -0
  98. package/skills/ti-howtos/references/location-and-maps.md +252 -0
  99. package/skills/ti-howtos/references/media-apis.md +210 -0
  100. package/skills/ti-howtos/references/notification-services.md +599 -0
  101. package/skills/ti-howtos/references/remote-data-sources.md +349 -0
  102. package/skills/ti-howtos/references/tutorials.md +502 -0
  103. package/skills/ti-howtos/references/using-modules.md +237 -0
  104. package/skills/ti-howtos/references/web-content-integration.md +307 -0
  105. package/skills/ti-howtos/references/webpack-build-pipeline.md +78 -0
  106. package/skills/ti-ui/SKILL.md +179 -0
  107. package/skills/ti-ui/references/accessibility-deep-dive.md +242 -0
  108. package/skills/ti-ui/references/animation-and-matrices.md +599 -0
  109. package/skills/ti-ui/references/application-structures.md +655 -0
  110. package/skills/ti-ui/references/custom-fonts-styling.md +579 -0
  111. package/skills/ti-ui/references/event-handling.md +393 -0
  112. package/skills/ti-ui/references/gestures.md +473 -0
  113. package/skills/ti-ui/references/icons-and-splash-screens.md +409 -0
  114. package/skills/ti-ui/references/layouts-and-positioning.md +462 -0
  115. package/skills/ti-ui/references/listviews-and-performance.md +619 -0
  116. package/skills/ti-ui/references/orientation.md +362 -0
  117. package/skills/ti-ui/references/platform-ui-android.md +635 -0
  118. package/skills/ti-ui/references/platform-ui-ios.md +469 -0
  119. package/skills/ti-ui/references/scrolling-views.md +252 -0
  120. package/skills/ti-ui/references/tableviews.md +568 -0
@@ -0,0 +1,783 @@
1
+ # iOS Platform Deep Dives
2
+
3
+ ## Table of Contents
4
+
5
+ - [iOS Platform Deep Dives](#ios-platform-deep-dives)
6
+ - [Table of Contents](#table-of-contents)
7
+ - [1. iOS 17+ Privacy Requirements (Critical)](#1-ios-17-privacy-requirements-critical)
8
+ - [PrivacyInfo.xcprivacy File](#privacyinfoxcprivacy-file)
9
+ - [2. Background Services \& Silent Push](#2-background-services--silent-push)
10
+ - [Overview](#overview)
11
+ - [Silent Push (Background Update)](#silent-push-background-update)
12
+ - [3. iCloud Services \& Backup Control](#3-icloud-services--backup-control)
13
+ - [Disable Individual Backup (Best Practice)](#disable-individual-backup-best-practice)
14
+ - [Recursive Folder Backup Disable](#recursive-folder-backup-disable)
15
+ - [4. WatchKit \& Ti.WatchSession](#4-watchkit--tiwatchsession)
16
+ - [Activate Session](#activate-session)
17
+ - [Send Message (Immediate)](#send-message-immediate)
18
+ - [Receive Data from Watch](#receive-data-from-watch)
19
+ - [5. SiriKit \& Siri Intents](#5-sirikit--siri-intents)
20
+ - [Configuration in tiapp.xml](#configuration-in-tiappxml)
21
+ - [Siri Extensions](#siri-extensions)
22
+ - [6. Spotlight Search (Core Spotlight)](#6-spotlight-search-core-spotlight)
23
+ - [7. Core Motion Module](#7-core-motion-module)
24
+ - [Overview](#overview-1)
25
+ - [Basic Workflow](#basic-workflow)
26
+ - [Coordinate System](#coordinate-system)
27
+ - [Accelerometer](#accelerometer)
28
+ - [Gyroscope](#gyroscope)
29
+ - [Magnetometer](#magnetometer)
30
+ - [Device Motion](#device-motion)
31
+ - [Activity API](#activity-api)
32
+ - [Pedometer](#pedometer)
33
+ - [Core Motion Best Practices](#core-motion-best-practices)
34
+ - [3. Spotlight Search](#3-spotlight-search)
35
+ - [Overview](#overview-2)
36
+ - [Creating Searchable Items](#creating-searchable-items)
37
+ - [Indexing Items](#indexing-items)
38
+ - [Deleting from Index](#deleting-from-index)
39
+ - [Handling Search Results](#handling-search-results)
40
+ - [Best Practices](#best-practices)
41
+ - [8. Handoff User Activities](#8-handoff-user-activities)
42
+ - [Handling Incoming Handoff](#handling-incoming-handoff)
43
+ - [Invalidating Activities](#invalidating-activities)
44
+ - [Declaring Activity Types in tiapp.xml](#declaring-activity-types-in-tiappxml)
45
+ - [5. iCloud Services](#5-icloud-services)
46
+ - [Keychain Storage](#keychain-storage)
47
+ - [Document Picker](#document-picker)
48
+ - [CloudKit](#cloudkit)
49
+ - [6. WatchKit Integration](#6-watchkit-integration)
50
+ - [Overview](#overview-3)
51
+ - [Integration Steps](#integration-steps)
52
+ - [Watch Connectivity](#watch-connectivity)
53
+ - [7. SiriKit Integration](#7-sirikit-integration)
54
+ - [Overview](#overview-4)
55
+ - [Supported Intents (iOS 10+)](#supported-intents-ios-10)
56
+ - [Implementation](#implementation)
57
+ - [Voice Shortcuts (iOS 12+)](#voice-shortcuts-ios-12)
58
+ - [8. Additional iOS Features](#8-additional-ios-features)
59
+ - [3D Touch (Force Touch)](#3d-touch-force-touch)
60
+ - [Haptic Feedback](#haptic-feedback)
61
+ - [Document Interaction](#document-interaction)
62
+ - [Best Practices Summary](#best-practices-summary)
63
+
64
+ ---
65
+
66
+ ## 1. iOS 17+ Privacy Requirements (Critical)
67
+ Apple requires declaring the use of certain APIs to prevent "fingerprinting".
68
+
69
+ ### PrivacyInfo.xcprivacy File
70
+ Create this file in `app/assets/iphone/` (Alloy) or `Resources/iphone/` (Classic):
71
+ ```xml
72
+ <?xml version="1.0" encoding="UTF-8"?>
73
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
74
+ <plist version="1.0">
75
+ <dict>
76
+ <key>NSPrivacyAccessedAPITypes</key>
77
+ <array>
78
+ <dict>
79
+ <key>NSPrivacyAccessedAPIType</key>
80
+ <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
81
+ <key>NSPrivacyAccessedAPITypeReasons</key>
82
+ <array><string>AC6B.1</string></array>
83
+ </dict>
84
+ </array>
85
+ </dict>
86
+ </plist>
87
+ ```
88
+ *Common categories: `UserDefaults` (Ti.App.Properties), `FileTimestamp` (file.createdAt), `SystemBootTime`.*
89
+
90
+ ## 2. Background Services & Silent Push
91
+
92
+ ### Overview
93
+ iOS allows limited background execution. For large downloads, use the `com.titaniumsdk.urlSession` module.
94
+
95
+ ### Silent Push (Background Update)
96
+ Allows waking up the app to download content without showing a notification to the user.
97
+
98
+ **tiapp.xml**:
99
+ ```xml
100
+ <key>UIBackgroundModes</key>
101
+ <array>
102
+ <string>remote-notification</string>
103
+ </array>
104
+ ```
105
+
106
+ **app.js**:
107
+ ```javascript
108
+ Ti.App.iOS.addEventListener('silentpush', (e) => {
109
+ // Start download or update
110
+ Ti.API.info(`Data received: ${JSON.stringify(e)}`);
111
+
112
+ // Mandatory to call upon completion (max 30 seconds)
113
+ Ti.App.iOS.endBackgroundHandler(e.handlerId);
114
+ });
115
+ ```
116
+
117
+ ## 3. iCloud Services & Backup Control
118
+
119
+ ### Disable Individual Backup (Best Practice)
120
+ Apple rejects apps that upload unnecessary data to iCloud. Disable backup for temporary or recreatable files.
121
+
122
+ ```javascript
123
+ const file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'cache.dat');
124
+ file.remoteBackup = false; // Prevents upload to iCloud/iTunes
125
+ ```
126
+
127
+ ### Recursive Folder Backup Disable
128
+ ```javascript
129
+ function disableiCloudBackup(folder) {
130
+ const dir = Ti.Filesystem.getFile(folder);
131
+ const files = dir.getDirectoryListing();
132
+ files.forEach((name) => {
133
+ const f = Ti.Filesystem.getFile(folder, name);
134
+ f.remoteBackup = false;
135
+ if (f.isDirectory()) disableiCloudBackup(f.nativePath);
136
+ });
137
+ }
138
+ ```
139
+
140
+ ## 4. WatchKit & Ti.WatchSession
141
+
142
+ For watchOS 2+, use `Ti.WatchSession` for bidirectional communication.
143
+
144
+ ### Activate Session
145
+ ```javascript
146
+ if (Ti.WatchSession.isSupported) {
147
+ Ti.WatchSession.activateSession();
148
+ }
149
+ ```
150
+
151
+ ### Send Message (Immediate)
152
+ ```javascript
153
+ if (Ti.WatchSession.isReachable) {
154
+ Ti.WatchSession.sendMessage({
155
+ orderId: '123',
156
+ status: 'shipped'
157
+ });
158
+ }
159
+ ```
160
+
161
+ ### Receive Data from Watch
162
+ ```javascript
163
+ Ti.WatchSession.addEventListener('receivemessage', (e) => {
164
+ Ti.API.info(`Message from Watch: ${e.message}`);
165
+ });
166
+ ```
167
+
168
+ ## 5. SiriKit & Siri Intents
169
+
170
+ Allows your app to respond to Siri voice commands (Messaging, Payments, Workouts).
171
+
172
+ ### Configuration in tiapp.xml
173
+ ```xml
174
+ <key>NSSiriUsageDescription</key>
175
+ <string>Siri will use your voice to send messages in this app.</string>
176
+ ```
177
+
178
+ ### Siri Extensions
179
+ Requires creating an **Intents Extension** in Xcode and adding it to the `extensions/` folder of your project. Then register it in `tiapp.xml`:
180
+ ```xml
181
+ <ios>
182
+ <extensions>
183
+ <extension projectPath="extensions/SiriIntent/SiriIntent.xcodeproj">
184
+ <target name="SiriIntent">
185
+ <provisioning-profiles>
186
+ <device>PROVISIONING_PROFILE_UUID</device>
187
+ </provisioning-profiles>
188
+ </target>
189
+ </extension>
190
+ </extensions>
191
+ </ios>
192
+ ```
193
+
194
+ ## 6. Spotlight Search (Core Spotlight)
195
+
196
+ Indexes your app's content to appear in global iOS search results.
197
+
198
+ ```javascript
199
+ const itemAttr = Ti.App.iOS.createSearchableItemAttributeSet({
200
+ itemContentType: Ti.App.iOS.UTTYPE_TEXT,
201
+ title: 'My Article',
202
+ contentDescription: 'Content description...',
203
+ keywords: ['titanium', 'help']
204
+ });
205
+
206
+ const item = Ti.App.iOS.createSearchableItem({
207
+ uniqueIdentifier: 'id-123',
208
+ domainIdentifier: 'articles',
209
+ attributeSet: itemAttr
210
+ });
211
+
212
+ const indexer = Ti.App.iOS.createSearchableIndex();
213
+ indexer.addToDefaultSearchableIndex([item], (e) => {
214
+ if (e.success) Ti.API.info('Indexed!');
215
+ });
216
+ ```
217
+
218
+ ## 7. Core Motion Module
219
+
220
+ ### Overview
221
+ Core Motion provides access to hardware sensors: accelerometer, gyroscope, magnetometer, and more.
222
+
223
+ **Requirements**:
224
+ - Add module to `tiapp.xml`:
225
+ ```xml
226
+ <modules>
227
+ <module platform="iphone">ti.coremotion</module>
228
+ </modules>
229
+ ```
230
+
231
+ - **Can only test on device** - not simulator
232
+ - Motion Activity permission required for Activity API
233
+
234
+ ### Basic Workflow
235
+
236
+ 1. Require the module:
237
+ ```javascript
238
+ var CoreMotion = require('ti.coremotion');
239
+ ```
240
+
241
+ 2. Check availability:
242
+ ```javascript
243
+ var Accelerometer = CoreMotion.createAccelerometer();
244
+ if (Accelerometer.isAccelerometerAvailable()) {
245
+ // Use accelerometer
246
+ }
247
+ ```
248
+
249
+ 3. Start updates:
250
+ ```javascript
251
+ Accelerometer.setAccelerometerUpdateInterval(1000); // 1 second
252
+ Accelerometer.startAccelerometerUpdates((e) => {
253
+ if (e.success) {
254
+ const data = e.acceleration;
255
+ Ti.API.info(`X: ${data.x} Y: ${data.y} Z: ${data.z}`);
256
+ }
257
+ });
258
+ ```
259
+
260
+ 4. Stop when done:
261
+ ```javascript
262
+ Accelerometer.stopAccelerometerUpdates();
263
+ ```
264
+
265
+ ### Coordinate System
266
+ Hold device in portrait mode, screen facing you:
267
+ - **X-axis**: Width (positive = right, negative = left)
268
+ - **Y-axis**: Height (positive = up, negative = down)
269
+ - **Z-axis**: Through screen (positive = toward screen, negative = behind)
270
+
271
+ ### Accelerometer
272
+
273
+ Measures g-force acceleration along three axes.
274
+
275
+ ```javascript
276
+ var CoreMotion = require('ti.coremotion');
277
+ var Accelerometer = CoreMotion.createAccelerometer();
278
+
279
+ if (Accelerometer.isAccelerometerAvailable()) {
280
+ Accelerometer.setAccelerometerUpdateInterval(100);
281
+ Accelerometer.startAccelerometerUpdates(function(e) {
282
+ if (e.success) {
283
+ var data = e.acceleration;
284
+ updateDisplay(data.x, data.y, data.z);
285
+ }
286
+ });
287
+ }
288
+ ```
289
+
290
+ **Use for**: Shake detection, device orientation, movement detection.
291
+
292
+ ### Gyroscope
293
+
294
+ Measures rotational rate along three axes (radians).
295
+
296
+ ```javascript
297
+ var Gyroscope = CoreMotion.createGyroscope();
298
+
299
+ if (Gyroscope.isGyroAvailable()) {
300
+ Gyroscope.setGyroUpdateInterval(100);
301
+ Gyroscope.startGyroUpdates(function(e) {
302
+ if (e.success) {
303
+ var data = e.rotationRate;
304
+ Ti.API.info('Rotation: X=' + data.x + ' Y=' + data.y + ' Z=' + data.z);
305
+ }
306
+ });
307
+ }
308
+ ```
309
+
310
+ **Use for**: Rotation gestures, 3D motion tracking, enhanced UI.
311
+
312
+ ### Magnetometer
313
+
314
+ Measures magnetic field strength (microteslas). Acts as digital compass.
315
+
316
+ ```javascript
317
+ var Magnetometer = CoreMotion.createMagnetometer();
318
+
319
+ if (Magnetometer.isMagnetometerAvailable()) {
320
+ Magnetometer.startMagnetometerUpdates();
321
+ // Or poll manually:
322
+ var data = Magnetometer.getMagnetometerData();
323
+ Ti.API.info('Magnetic field: ' + JSON.stringify(data.magneticField));
324
+ }
325
+ ```
326
+
327
+ **Use for**: Compass direction, magnetic field detection.
328
+
329
+ ### Device Motion
330
+
331
+ Combines accelerometer, gyroscope, magnetometer for attitude and user acceleration.
332
+
333
+ ```javascript
334
+ var DeviceMotion = CoreMotion.createDeviceMotion();
335
+
336
+ if (DeviceMotion.isDeviceMotionAvailable()) {
337
+ DeviceMotion.setDeviceMotionUpdateInterval(500);
338
+
339
+ // Check available reference frames
340
+ var frames = DeviceMotion.availableAttitudeReferenceFrames();
341
+
342
+ if (frames & CoreMotion.ATTITUDE_REFERENCE_FRAME_X_TRUE_NORTH_Z_VERTICAL) {
343
+ // Use true north reference
344
+ DeviceMotion.startDeviceMotionUpdatesUsingReferenceFrame(
345
+ { referenceFrame: CoreMotion.ATTITUDE_REFERENCE_FRAME_X_TRUE_NORTH_Z_VERTICAL },
346
+ (e) => {
347
+ if (e.success) {
348
+ // Attitude: orientation (pitch, roll, yaw)
349
+ const attitude = e.attitude;
350
+ Ti.API.info(`Pitch: ${attitude.pitch} Roll: ${attitude.roll} Yaw: ${attitude.yaw}`);
351
+
352
+ // User acceleration: force applied by user (not gravity)
353
+ const userAccel = e.userAcceleration;
354
+ }
355
+ }
356
+ );
357
+ }
358
+ }
359
+ ```
360
+
361
+ **Attitude formats**:
362
+ - Pitch/Roll/Yaw (Euler angles)
363
+ - Quaternion (w, x, y, z)
364
+ - Rotation Matrix (m11-m33)
365
+
366
+ **Reference Frames**:
367
+ - `ATTITUDE_REFERENCE_FRAME_X_ARBITRARY_Z_VERTICAL` - Default
368
+ - `ATTITUDE_REFERENCE_FRAME_X_ARBITRARY_CORRECTED_Z_VERTICAL` - Uses magnetometer for yaw
369
+ - `ATTITUDE_REFERENCE_FRAME_X_MAGNETIC_NORTH_Z_VERTICAL` - Magnetic north
370
+ - `ATTITUDE_REFERENCE_FRAME_X_TRUE_NORTH_Z_VERTICAL` - True north (requires location)
371
+
372
+ ### Activity API
373
+
374
+ ```javascript
375
+ const MotionActivity = CoreMotion.createMotionActivity();
376
+
377
+ MotionActivity.startActivityUpdates((e) => {
378
+ const activity = e.activity;
379
+
380
+ // Check confidence
381
+ if (activity.confidence !== CoreMotion.MOTION_ACTIVITY_CONFIDENCE_LOW) {
382
+ if (activity.walking) {
383
+ Ti.API.info('User is walking');
384
+ } else if (activity.running) {
385
+ Ti.API.info('User is running');
386
+ } else if (activity.automotive) {
387
+ Ti.API.info('User in vehicle');
388
+ } else if (activity.stationary) {
389
+ Ti.API.info('Device stationary');
390
+ }
391
+ }
392
+ });
393
+ ```
394
+
395
+ **Query historical activity**:
396
+ ```javascript
397
+ var endDate = new Date();
398
+ var startDate = new Date(endDate.getTime() - 60 * 60 * 1000); // 1 hour ago
399
+
400
+ MotionActivity.queryActivity({
401
+ start: startDate,
402
+ end: endDate
403
+ }, function(e) {
404
+ var activities = e.activities;
405
+ // Process historical data
406
+ });
407
+ ```
408
+
409
+ **Requires Motion Activity permission** in tiapp.xml:
410
+ ```xml
411
+ <key>NSMotionUsageDescription</key>
412
+ <string>Need motion data for fitness tracking</string>
413
+ ```
414
+
415
+ ### Pedometer
416
+
417
+ ```javascript
418
+ const Pedometer = CoreMotion.createPedometer();
419
+
420
+
421
+ if (Pedometer.isStepCountingAvailable()) {
422
+ // Start live updates
423
+ Pedometer.startPedometerUpdates({
424
+ start: new Date(new Date().getTime() - (60 * 60 * 1000)) // From 1 hour ago
425
+ }, (e) => {
426
+ Ti.API.info(`Steps: ${e.numberOfSteps}`);
427
+ Ti.API.info(`Distance: ${e.distance} meters`);
428
+ Ti.API.info(`Floors up: ${e.floorsAscended}`);
429
+ Ti.API.info(`Floors down: ${e.floorsDescended}`);
430
+ });
431
+ }
432
+
433
+ // Query historical data
434
+ var endDate = new Date();
435
+ var startDate = new Date(endDate.getTime() - 24 * 60 * 60 * 1000); // 24 hours ago
436
+
437
+ Pedometer.queryPedometerData({
438
+ start: startDate,
439
+ end: endDate
440
+ }, function(e) {
441
+ Ti.API.info('Steps in last 24h: ' + e.numberOfSteps);
442
+ });
443
+ ```
444
+
445
+ **Use for**: Fitness apps, step challenges, activity tracking.
446
+
447
+ ### Core Motion Best Practices
448
+
449
+ 1. **Always check availability** - Not all devices have all sensors
450
+ 2. **Set appropriate update intervals** - High frequency = more CPU/battery
451
+ 3. **Stop updates when not needed** - Conserve battery
452
+ 4. **Handle errors gracefully** - Sensor may fail or be unavailable
453
+ 5. **Test on physical device** - Sensors don't work in simulator
454
+
455
+ ## 3. Spotlight Search
456
+
457
+ ### Overview
458
+ Spotlight Search allows iOS to index your app's content, making it searchable from the home screen.
459
+
460
+ ### Creating Searchable Items
461
+
462
+ ```javascript
463
+ var SearchableItem = Ti.App.iOS.SearchableItem;
464
+
465
+ var item1 = SearchableItem.createSearchableItem({
466
+ uniqueIdentifier: 'article-123',
467
+ domainIdentifier: 'articles',
468
+ title: 'Titanium SDK Guide',
469
+ contentDescription: 'Complete guide to Titanium SDK development',
470
+ thumbnail: articleThumbnailImage, // Ti.Blob
471
+ keywords: ['titanium', 'mobile', 'javascript', 'ios', 'android']
472
+ });
473
+
474
+ var item2 = SearchableItem.createSearchableItem({
475
+ uniqueIdentifier: 'product-456',
476
+ domainIdentifier: 'products',
477
+ title: 'Product Name',
478
+ contentDescription: 'Product description here',
479
+ keywords: ['product', 'shopping']
480
+ });
481
+ ```
482
+
483
+ ### Indexing Items
484
+
485
+ ```javascript
486
+ var SearchableIndex = Ti.App.iOS.SearchableIndex;
487
+
488
+ SearchableIndex.indexSearchableItems([item1, item2], function(e) {
489
+ if (e.success) {
490
+ Ti.API.info('Indexing successful');
491
+ } else {
492
+ Ti.API.error('Indexing failed: ' + e.error);
493
+ }
494
+ });
495
+ ```
496
+
497
+ ### Deleting from Index
498
+
499
+ ```javascript
500
+ // Delete specific items
501
+ SearchableIndex.deleteSearchableItemsWithIdentifiers(['article-123'], function(e) {
502
+ if (e.success) {
503
+ Ti.API.info('Deleted successfully');
504
+ }
505
+ });
506
+
507
+ // Delete all items in domain
508
+ SearchableIndex.deleteSearchableItemsWithDomainIdentifiers(['articles'], function(e) {
509
+ if (e.success) {
510
+ Ti.API.info('Deleted all articles');
511
+ }
512
+ });
513
+
514
+ // Delete all
515
+ SearchableIndex.deleteAllSearchableItems(function(e) {
516
+ if (e.success) {
517
+ Ti.API.info('Cleared index');
518
+ }
519
+ });
520
+ ```
521
+
522
+ ### Handling Search Results
523
+
524
+ When user taps a Spotlight result, your app opens with the `continueactivity` event:
525
+
526
+ ```javascript
527
+ Ti.App.iOS.addEventListener('continueactivity', function(e) {
528
+ if (e.activityType === 'com.apple.core SpotlightQuery') {
529
+ var identifier = e.userInfo.identifier;
530
+ var domain = e.userInfo.domainIdentifier;
531
+
532
+ Ti.API.info('Spotlight search selected: ' + identifier);
533
+
534
+ // Navigate to appropriate content
535
+ if (domain === 'articles') {
536
+ openArticle(identifier);
537
+ } else if (domain === 'products') {
538
+ openProduct(identifier);
539
+ }
540
+ }
541
+ });
542
+ ```
543
+
544
+ **Important**: Use `NSUserActivityTypes` in tiapp.xml to declare supported activity types.
545
+
546
+ ### Best Practices
547
+
548
+ 1. **Index relevant content** - Don't index everything
549
+ 2. **Use meaningful keywords** - Help users find content
550
+ 3. **Provide thumbnails** - Improve visual recognition
551
+ 4. **Keep index updated** - Re-index when content changes
552
+ 5. **Delete obsolete items** - Don't clutter search results
553
+
554
+ ## 8. Handoff User Activities
555
+
556
+ ```javascript
557
+ const UserActivity = Ti.App.iOS.createUserActivity({
558
+ activityType: 'com.myapp.reading-article',
559
+ title: 'Reading: Titanium SDK Guide',
560
+ userInfo: {
561
+ articleId: '123',
562
+ scrollPosition: 450
563
+ },
564
+ webpageURL: 'https://myapp.com/articles/123' // For web fallback
565
+ });
566
+
567
+ // Mark as current activity
568
+ UserActivity.becomeCurrent();
569
+ ```
570
+
571
+ ### Handling Incoming Handoff
572
+
573
+ ```javascript
574
+ Ti.App.iOS.addEventListener('continueactivity', function(e) {
575
+ if (e.activityType === 'com.myapp.reading-article') {
576
+ var userInfo = e.userInfo;
577
+
578
+ // Restore activity state
579
+ openArticle(userInfo.articleId, {
580
+ scrollTo: userInfo.scrollPosition
581
+ });
582
+ }
583
+ });
584
+ ```
585
+
586
+ ### Invalidating Activities
587
+
588
+ ```javascript
589
+ // When user closes article
590
+ UserActivity.invalidate();
591
+ ```
592
+
593
+ ### Declaring Activity Types in tiapp.xml
594
+
595
+ ```xml
596
+ <key>NSUserActivityTypes</key>
597
+ <array>
598
+ <string>com.myapp.reading-article</string>
599
+ <string>com.myapp.editing-document</string>
600
+ <string>com.myapp.viewing-product</string>
601
+ </array>
602
+ ```
603
+
604
+ ## 5. iCloud Services
605
+
606
+ ### Keychain Storage
607
+
608
+ Securely sync small pieces of data (passwords, tokens) across user's devices.
609
+
610
+ ```javascript
611
+ // Store value
612
+ Ti.App.iOS.setKeychainItem('username', 'john@example.com');
613
+ Ti.App.iOS.setKeychainItem('authToken', 'abc123token');
614
+
615
+ // Retrieve value
616
+ var username = Ti.App.iOS.getKeychainItem('username');
617
+
618
+ // Remove value
619
+ Ti.App.iOS.removeKeychainItem('authToken');
620
+ ```
621
+
622
+ **Use for**: Syncing user credentials, preferences, small data.
623
+
624
+ **Requires** iCloud capability enabled in Xcode project.
625
+
626
+ ### Document Picker
627
+
628
+ ```javascript
629
+ const DocumentPicker = Ti.UI.iOS.createDocumentPicker({
630
+ mode: Ti.UI.iOS.DOCUMENT_PICKER_MODE_OPEN
631
+ });
632
+
633
+ DocumentPicker.addEventListener('select', (e) => {
634
+ const url = e.url; // File URL
635
+ Ti.API.info(`Selected: ${url}`);
636
+
637
+ // Read file
638
+ const file = Ti.Filesystem.getFile(url);
639
+ const contents = file.read();
640
+ });
641
+
642
+ DocumentPicker.addEventListener('cancel', function(e) {
643
+ Ti.API.info('Document picker canceled');
644
+ });
645
+
646
+ // Show picker
647
+ DocumentPicker.show();
648
+ ```
649
+
650
+ **Modes**:
651
+ - `DOCUMENT_PICKER_MODE_OPEN` - Open existing document
652
+ - `DOCUMENT_PICKER_MODE_EXPORT` - Export to document provider
653
+ - `DOCUMENT_PICKER_MODE_IMPORT` - Import copy of document
654
+ - `DOCUMENT_PICKER_MODE_MOVE` - Move document to app's sandbox
655
+
656
+ ### CloudKit
657
+
658
+ For more complex iCloud data sync, consider using CloudKit modules or Hyperloop.
659
+
660
+ ## 6. WatchKit Integration
661
+
662
+ ### Overview
663
+ Integrate Apple Watch apps built in Xcode with Titanium app.
664
+
665
+ ### Integration Steps
666
+
667
+ 1. **Create WatchKit app** in Xcode
668
+ 2. **Add App Group** to both iOS and Watch targets
669
+ 3. **Use App Group** for shared data:
670
+
671
+ ```javascript
672
+ // In Titanium app, use App Group container
673
+ var container = 'group.com.myapp.shared';
674
+ var sharedDefaults = Ti.App.iOS.createUserDefaults({ suiteName: container });
675
+
676
+ sharedDefaults.setString('watchData', JSON.stringify(data));
677
+ ```
678
+
679
+ 4. **Watch app reads shared data** using same App Group container
680
+
681
+ ### Watch Connectivity
682
+
683
+ For bidirectional communication, use Watch Connectivity framework via Hyperloop or modules.
684
+
685
+ ## 7. SiriKit Integration
686
+
687
+ ### Overview
688
+ SiriKit allows your app to handle specific intents via Siri voice commands.
689
+
690
+ ### Supported Intents (iOS 10+)
691
+ - Messaging (send/read messages)
692
+ - Payments (send/request money)
693
+ - Workouts (start/stop/pause/resume)
694
+ - Rides (book ride)
695
+ - Photo (search/send photos)
696
+ - VoIP calling
697
+
698
+ ### Implementation
699
+
700
+ Requires native module or Hyperloop to implement Intent Extension.
701
+
702
+ **Basic steps**:
703
+ 1. Define supported intents in tiapp.xml
704
+ 2. Create Intent Extension in Xcode
705
+ 3. Handle intents in extension code
706
+ 4. Provide UI for Siri interaction
707
+
708
+ ### Voice Shortcuts (iOS 12+)
709
+
710
+ Add custom voice shortcuts for app actions:
711
+
712
+ ```javascript
713
+ var INVoiceShortcut = Ti.UI.iOS.createINVoiceShortcut({
714
+ phrase: 'Open My Article',
715
+ activityType: 'com.myapp.reading-article',
716
+ userInfo: { articleId: '123' }
717
+ });
718
+
719
+ // Present to user for recording
720
+ INVoiceShortcut.present();
721
+ ```
722
+
723
+ ## 8. Additional iOS Features
724
+
725
+ ### 3D Touch (Force Touch)
726
+
727
+ ```javascript
728
+ // Check for 3D Touch support
729
+ if (Ti.Platform.forceTouchSupported) {
730
+ view.addEventListener('touchstart', (e) => {
731
+ const force = e.force || 0;
732
+ const maxForce = e.maximumForce || 1;
733
+
734
+ if (force / maxForce > 0.75) {
735
+ // Deep press
736
+ showQuickActions();
737
+ }
738
+ });
739
+ }
740
+ ```
741
+
742
+ ### Haptic Feedback
743
+
744
+ ```javascript
745
+ // Generate haptic feedback
746
+ const generator = Ti.UI.iOS.createHapticFeedbackGenerator();
747
+
748
+ // Impact feedback (light, medium, heavy)
749
+ generator.impactOccurred(Ti.UI.iOS.HAPTIC_FEEDBACK_STYLE_MEDIUM);
750
+
751
+ // Selection feedback
752
+ generator.selectionChanged();
753
+
754
+ // Notification feedback (success, warning, error)
755
+ generator.notificationOccurred(Ti.UI.iOS.HAPTIC_FEEDBACK_TYPE_SUCCESS);
756
+ ```
757
+
758
+ ### Document Interaction
759
+
760
+ Open documents in other apps:
761
+
762
+ ```javascript
763
+ var docController = Ti.UI.iOS.createDocumentViewer({
764
+ url: file.nativePath
765
+ });
766
+
767
+ docController.addEventListener('complete', function(e) {
768
+ Ti.API.info('Document interaction complete');
769
+ });
770
+
771
+ win.add(docController);
772
+ ```
773
+
774
+ ## Best Practices Summary
775
+
776
+ 1. **Background Services**: Use sparingly, stop when done
777
+ 2. **Core Motion**: Always check availability, test on device
778
+ 3. **Spotlight**: Index content as it changes
779
+ 4. **Handoff**: Provide web URL fallback
780
+ 5. **iCloud**: Use for small synced data, not large files
781
+ 6. **SiriKit**: Requires native extension, use only if beneficial
782
+ 7. **Permissions**: Always include usage descriptions in tiapp.xml
783
+ 8. **Testing**: Many features require physical device testing