@maccesar/titools 2.0.7 → 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 +17 -17
  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,68 +1,5 @@
1
1
  # iOS Platform Deep Dives
2
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
3
  ## 1. iOS 17+ Privacy Requirements (Critical)
67
4
  Apple requires declaring the use of certain APIs to prevent "fingerprinting".
68
5
 
@@ -108,12 +45,71 @@ Allows waking up the app to download content without showing a notification to t
108
45
  Ti.App.iOS.addEventListener('silentpush', (e) => {
109
46
  // Start download or update
110
47
  Ti.API.info(`Data received: ${JSON.stringify(e)}`);
111
-
48
+
112
49
  // Mandatory to call upon completion (max 30 seconds)
113
50
  Ti.App.iOS.endBackgroundHandler(e.handlerId);
114
51
  });
115
52
  ```
116
53
 
54
+ ### Background Fetch
55
+ ```javascript
56
+ // Enable in tiapp.xml:
57
+ // <key>UIBackgroundModes</key>
58
+ // <array><string>fetch</string></array>
59
+
60
+ // Set minimum fetch interval
61
+ Ti.App.iOS.setMinimumBackgroundFetchInterval(Ti.App.iOS.BACKGROUNDFETCHINTERVAL_MIN);
62
+
63
+ Ti.App.iOS.addEventListener('backgroundfetch', (e) => {
64
+ // Fetch new data
65
+ Ti.API.info('Background fetch triggered');
66
+
67
+ // Must call endBackgroundHandler when done (max 30 seconds)
68
+ Ti.App.iOS.endBackgroundHandler(e.handlerId);
69
+ });
70
+
71
+ // To disable background fetch:
72
+ // Ti.App.iOS.setMinimumBackgroundFetchInterval(Ti.App.iOS.BACKGROUNDFETCHINTERVAL_NEVER);
73
+ ```
74
+
75
+ ### URL Session Module
76
+ For large downloads that continue even if the app is suspended, use the `com.titaniumsdk.urlSession` module:
77
+
78
+ ```javascript
79
+ const urlSession = require('com.titaniumsdk.urlSession');
80
+
81
+ const config = urlSession.createSessionConfiguration({
82
+ identifier: 'com.myapp.downloads'
83
+ });
84
+
85
+ const session = urlSession.createSession({
86
+ configuration: config
87
+ });
88
+
89
+ // Start a download task
90
+ session.downloadTask({
91
+ url: 'https://example.com/largefile.zip'
92
+ });
93
+
94
+ // Monitor progress
95
+ session.addEventListener('downloadprogress', (e) => {
96
+ Ti.API.info(`Progress: ${e.totalBytesWritten}/${e.totalBytesExpectedToWrite}`);
97
+ });
98
+
99
+ session.addEventListener('downloadcompleted', (e) => {
100
+ Ti.API.info(`Download saved to: ${e.data}`);
101
+ });
102
+
103
+ session.addEventListener('sessioncompleted', (e) => {
104
+ if (!e.success) {
105
+ Ti.API.error(`Session error: ${e.errorDescription}`);
106
+ }
107
+ });
108
+
109
+ // Invalidate session when no longer needed
110
+ session.invalidateAndCancel();
111
+ ```
112
+
117
113
  ## 3. iCloud Services & Backup Control
118
114
 
119
115
  ### Disable Individual Backup (Best Practice)
@@ -165,6 +161,25 @@ Ti.WatchSession.addEventListener('receivemessage', (e) => {
165
161
  });
166
162
  ```
167
163
 
164
+ ### Provisioning Profiles for Watch
165
+ Both the iOS app and WatchKit extension need separate provisioning profiles. Configure in tiapp.xml:
166
+ ```xml
167
+ <ios>
168
+ <extensions>
169
+ <extension projectPath="extensions/WatchApp/WatchApp.xcodeproj">
170
+ <target name="WatchApp Extension">
171
+ <provisioning-profiles>
172
+ <device>WATCH_DEV_PROFILE_UUID</device>
173
+ <dist-appstore>WATCH_DIST_PROFILE_UUID</dist-appstore>
174
+ </provisioning-profiles>
175
+ </target>
176
+ </extension>
177
+ </extensions>
178
+ </ios>
179
+ ```
180
+
181
+ > **Note**: For Xcode 8+, ensure your Team ID matches across all targets.
182
+
168
183
  ## 5. SiriKit & Siri Intents
169
184
 
170
185
  Allows your app to respond to Siri voice commands (Messaging, Payments, Workouts).
@@ -191,6 +206,16 @@ Requires creating an **Intents Extension** in Xcode and adding it to the `extens
191
206
  </ios>
192
207
  ```
193
208
 
209
+ ### Implementation Steps
210
+ 1. **Register App ID** with SiriKit capability in Apple Developer Portal
211
+ 2. **Create Intent Extension** in Xcode (File > New > Target > Intents Extension)
212
+ 3. **Configure entitlements** — add `com.apple.developer.siri` entitlement
213
+ 4. **Add extension to project** — place in `extensions/` folder
214
+ 5. **Register in tiapp.xml** with provisioning profiles for the extension target
215
+ 6. **Handle intents** in the native extension code (Swift/Objective-C)
216
+
217
+ > **Note**: SiriKit requires native code in the Intent Extension. The Titanium app receives results via `continueactivity` events.
218
+
194
219
  ## 6. Spotlight Search (Core Spotlight)
195
220
 
196
221
  Indexes your app's content to appear in global iOS search results.
@@ -417,7 +442,6 @@ MotionActivity.queryActivity({
417
442
  ```javascript
418
443
  const Pedometer = CoreMotion.createPedometer();
419
444
 
420
-
421
445
  if (Pedometer.isStepCountingAvailable()) {
422
446
  // Start live updates
423
447
  Pedometer.startPedometerUpdates({
@@ -452,105 +476,6 @@ Pedometer.queryPedometerData({
452
476
  4. **Handle errors gracefully** - Sensor may fail or be unavailable
453
477
  5. **Test on physical device** - Sensors don't work in simulator
454
478
 
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
479
  ## 8. Handoff User Activities
555
480
 
556
481
  ```javascript
@@ -601,126 +526,13 @@ UserActivity.invalidate();
601
526
  </array>
602
527
  ```
603
528
 
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
- ```
529
+ ### Requirements
530
+ - Both devices must be signed into the same iCloud account
531
+ - Bluetooth LE must be enabled on both devices
532
+ - Both devices must be on the same Wi-Fi network
533
+ - Test with Safari first to verify Handoff works between your devices
722
534
 
723
- ## 8. Additional iOS Features
535
+ ## 9. Additional iOS Features
724
536
 
725
537
  ### 3D Touch (Force Touch)
726
538
 
@@ -1,41 +1,5 @@
1
1
  # Local Data Sources
2
2
 
3
- ## Table of Contents
4
-
5
- - [Local Data Sources](#local-data-sources)
6
- - [Table of Contents](#table-of-contents)
7
- - [1. Filesystem Access and Storage](#1-filesystem-access-and-storage)
8
- - [Modules Overview](#modules-overview)
9
- - [Storage Locations](#storage-locations)
10
- - [File Operations](#file-operations)
11
- - [Getting a File Handle](#getting-a-file-handle)
12
- - [Writing Files](#writing-files)
13
- - [Reading Files](#reading-files)
14
- - [Appending](#appending)
15
- - [Creating/Copying](#creatingcopying)
16
- - [Renaming](#renaming)
17
- - [Deleting](#deleting)
18
- - [Directory Operations](#directory-operations)
19
- - [Case Sensitivity Warning](#case-sensitivity-warning)
20
- - [2. SQLite Database](#2-sqlite-database)
21
- - [Opening Databases](#opening-databases)
22
- - [Querying Data](#querying-data)
23
- - [Parameterized Queries](#parameterized-queries)
24
- - [Data Modification](#data-modification)
25
- - [**CRITICAL**: Always Close Connections](#critical-always-close-connections)
26
- - [3. Properties API (Ti.App.Properties)](#3-properties-api-tiappproperties)
27
- - [Overview](#overview)
28
- - [Data Type Methods](#data-type-methods)
29
- - [Usage Examples](#usage-examples)
30
- - [Storing Complex Objects as JSON](#storing-complex-objects-as-json)
31
- - [Platform Storage](#platform-storage)
32
- - [4. Advanced Data Manipulation (Buffer, Codec, and Streams)](#4-advanced-data-manipulation-buffer-codec-and-streams)
33
- - [5. Choosing a Persistence Strategy](#5-choosing-a-persistence-strategy)
34
- - [Decision Guide](#decision-guide)
35
- - [Best Practices](#best-practices)
36
-
37
- ---
38
-
39
3
  ## 1. Filesystem Access and Storage
40
4
 
41
5
  ### Modules Overview
@@ -140,6 +104,14 @@ Android and Mobile Web use case-sensitive filesystems. File names referenced in
140
104
 
141
105
  ## 2. SQLite Database
142
106
 
107
+ ### Installing a Pre-populated Database
108
+ Ship a database with your app and install it on first launch:
109
+ ```javascript
110
+ // Copies db from Resources/ (or app/assets/) to applicationDataDirectory
111
+ const db = Ti.Database.install('seeds/mydata.sqlite', 'mydata');
112
+ // On subsequent launches, install() just opens the existing database
113
+ ```
114
+
143
115
  ### Opening Databases
144
116
 
145
117
  ```javascript
@@ -188,7 +160,8 @@ db.execute(`INSERT INTO users (name, age) VALUES ('${name}', ${age})`);
188
160
  ```javascript
189
161
  // INSERT
190
162
  db.execute('INSERT INTO users (name, age) VALUES (?, ?)', ['Jane', 30]);
191
- const lastId = db.lastInsertRowId; // Get inserted ID
163
+ const lastId = db.lastInsertRowId; // ID of the last inserted row
164
+ const affected = db.rowsAffected; // number of rows changed by last statement
192
165
 
193
166
  // UPDATE
194
167
  db.execute('UPDATE users SET age = ? WHERE name = ?', [31, 'Jane']);
@@ -198,6 +171,41 @@ const rowsAffected = db.rowsAffected;
198
171
  db.execute('DELETE FROM users WHERE age < ?', [18]);
199
172
  ```
200
173
 
174
+ ### Transactions for Batch Operations
175
+ Use transactions to dramatically improve performance for multiple inserts/updates:
176
+ ```javascript
177
+ const db = Ti.Database.open('mydb');
178
+ db.execute('BEGIN');
179
+ try {
180
+ for (let i = 0; i < items.length; i++) {
181
+ db.execute('INSERT INTO products (name, price) VALUES (?, ?)', items[i].name, items[i].price);
182
+ }
183
+ db.execute('COMMIT');
184
+ } catch (e) {
185
+ db.execute('ROLLBACK');
186
+ Ti.API.error(`Transaction failed: ${e.message}`);
187
+ }
188
+ db.close();
189
+ ```
190
+
191
+ > **Performance**: Wrapping 1000 inserts in a transaction can be 10-100x faster than individual inserts.
192
+
193
+ ### SQLite Limitations
194
+ - No `FULL OUTER JOIN` support — use `LEFT JOIN` with `UNION`
195
+ - Limited `ALTER TABLE` — can only `ADD COLUMN` or `RENAME TABLE`, cannot drop/modify columns
196
+ - No built-in referential integrity (foreign key enforcement) — enable with `PRAGMA foreign_keys = ON`
197
+ - No native boolean type — use INTEGER (0/1)
198
+
199
+ ### Disable iCloud Backup for Databases (iOS)
200
+ iOS automatically backs up databases to iCloud. For large or recreatable databases, disable this:
201
+ ```javascript
202
+ const db = Ti.Database.open('mydb');
203
+ db.file.setRemoteBackup(false);
204
+ db.close();
205
+ ```
206
+
207
+ > **Important**: Apple may reject apps that back up large recreatable data to iCloud.
208
+
201
209
  ### **CRITICAL**: Always Close Connections
202
210
 
203
211
  ```javascript
@@ -1,33 +1,5 @@
1
1
  # Location Services and Maps
2
2
 
3
- ## Table of Contents
4
-
5
- - [Location Services and Maps](#location-services-and-maps)
6
- - [Table of Contents](#table-of-contents)
7
- - [1. GPS Position Tracking](#1-gps-position-tracking)
8
- - [FusedLocationProvider (Android)](#fusedlocationprovider-android)
9
- - [Accuracy Configuration](#accuracy-configuration)
10
- - [Android Configuration Modes](#android-configuration-modes)
11
- - [One-Time Position](#one-time-position)
12
- - [Continuous Monitoring](#continuous-monitoring)
13
- - [Lifecycle Management (Critical for Battery)](#lifecycle-management-critical-for-battery)
14
- - [Compass/Heading](#compassheading)
15
- - [Geocoding](#geocoding)
16
- - [Forward Geocoding (Address → Coordinates)](#forward-geocoding-address--coordinates)
17
- - [Reverse Geocoding (Coordinates → Places)](#reverse-geocoding-coordinates--places)
18
- - [2. Native Maps (Platform-Specific Details)](#2-native-maps-platform-specific-details)
19
- - [Common Map Patterns](#common-map-patterns)
20
- - [Add Annotation After Map Creation](#add-annotation-after-map-creation)
21
- - [Remove Annotation](#remove-annotation)
22
- - [Remove All Annotations](#remove-all-annotations)
23
- - [Select Annotation Programmatically](#select-annotation-programmatically)
24
- - [Deselect Annotation](#deselect-annotation)
25
- - [Set Region with Animation](#set-region-with-animation)
26
- - [Zoom to Annotations](#zoom-to-annotations)
27
- - [Best Practices](#best-practices)
28
-
29
- ---
30
-
31
3
  ## 1. GPS Position Tracking
32
4
 
33
5
  ### FusedLocationProvider (Android)
@@ -51,6 +23,8 @@ Ti.Geolocation.headingFilter = 5; // degrees - only fire if heading changed X
51
23
  Ti.Geolocation.preferredProvider = Ti.Geolocation.PROVIDER_GPS; // or PROVIDER_NETWORK
52
24
  ```
53
25
 
26
+ > **Note**: On many Android devices, a low-precision "passive" location provider is always enabled, even when the user disables GPS and Network providers. Therefore `Ti.Geolocation.locationServicesEnabled` may always return `true` on these devices.
27
+
54
28
  ### Android Configuration Modes
55
29
 
56
30
  **Simple Mode** (ACCURACY_HIGH/LOW):
@@ -69,6 +43,34 @@ Ti.Geolocation.Android.addLocationProvider(providerGps);
69
43
  Ti.Geolocation.Android.manualMode = true;
70
44
  ```
71
45
 
46
+ ### Location Permissions
47
+
48
+ ```javascript
49
+ // Check permissions
50
+ if (Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE)) {
51
+ startTracking();
52
+ } else {
53
+ Ti.Geolocation.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE, (e) => {
54
+ if (e.success) {
55
+ startTracking();
56
+ } else {
57
+ Ti.API.error(`Permission denied: ${e.error}`);
58
+ }
59
+ });
60
+ }
61
+ ```
62
+
63
+ **iOS plist keys** (tiapp.xml):
64
+ ```xml
65
+ <key>NSLocationWhenInUseUsageDescription</key>
66
+ <string>We need your location to show nearby places</string>
67
+ <!-- For background location: -->
68
+ <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
69
+ <string>We need background location for navigation</string>
70
+ ```
71
+
72
+ > **Note (iOS 11+)**: You must include `NSLocationAlwaysAndWhenInUseUsageDescription` even when requesting "Always" permission. Users can still choose "When in Use" even if your app requests "Always".
73
+
72
74
  ### One-Time Position
73
75
 
74
76
  ```javascript
@@ -147,6 +149,12 @@ Ti.Geolocation.addEventListener('heading', (e) => {
147
149
  });
148
150
  ```
149
151
 
152
+ The heading event object includes:
153
+ - `heading.magneticHeading` — degrees relative to magnetic north
154
+ - `heading.trueHeading` — degrees relative to true north (requires location)
155
+ - `heading.accuracy` — deviation in degrees (lower is better)
156
+ - `heading.x`, `heading.y`, `heading.z` — raw magnetometer data (microteslas)
157
+
150
158
  ---
151
159
 
152
160
  ## Geocoding
@@ -161,6 +169,17 @@ Ti.Geolocation.forwardGeocoder('440 Bernardo Ave Mountain View CA', (e) => {
161
169
  });
162
170
  ```
163
171
 
172
+ **With error handling:**
173
+ ```javascript
174
+ Ti.Geolocation.forwardGeocoder('1600 Amphitheatre Pkwy, Mountain View, CA', (e) => {
175
+ if (!e.success || e.error) {
176
+ Ti.API.error(`Geocoding failed: ${e.error}`);
177
+ return;
178
+ }
179
+ Ti.API.info(`Lat: ${e.latitude}, Lng: ${e.longitude}`);
180
+ });
181
+ ```
182
+
164
183
  ### Reverse Geocoding (Coordinates → Places)
165
184
 
166
185
  ```javascript