@maccesar/titools 2.2.4 → 2.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -23
- package/agents/ti-pro.md +17 -17
- package/lib/commands/update.js +6 -14
- package/lib/downloader.js +17 -2
- package/package.json +1 -1
- package/skills/alloy-guides/SKILL.md +31 -31
- package/skills/alloy-guides/references/CONCEPTS.md +3 -3
- package/skills/alloy-guides/references/CONTROLLERS.md +1 -1
- package/skills/alloy-guides/references/MODELS.md +6 -6
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +1 -1
- package/skills/alloy-guides/references/VIEWS_XML.md +1 -1
- package/skills/alloy-guides/references/WIDGETS.md +1 -1
- package/skills/alloy-howtos/SKILL.md +27 -27
- package/skills/alloy-howtos/references/best_practices.md +9 -9
- package/skills/alloy-howtos/references/cli_reference.md +14 -14
- package/skills/alloy-howtos/references/config_files.md +16 -16
- package/skills/alloy-howtos/references/custom_tags.md +16 -16
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +11 -15
- package/skills/alloy-howtos/references/samples.md +19 -19
- package/skills/purgetss/SKILL.md +11 -1
- package/skills/purgetss/references/animation-system.md +1 -1
- package/skills/purgetss/references/cli-commands.md +3 -3
- package/skills/purgetss/references/customization-deep-dive.md +1 -1
- package/skills/purgetss/references/dynamic-component-creation.md +1 -1
- package/skills/purgetss/references/icon-fonts.md +4 -0
- package/skills/purgetss/references/installation-setup.md +8 -1
- package/skills/purgetss/references/migration-guide.md +4 -0
- package/skills/purgetss/references/tikit-components.md +193 -204
- package/skills/purgetss/references/ui-ux-design.md +1 -1
- package/skills/ti-expert/SKILL.md +78 -118
- package/skills/ti-expert/references/alloy-builtins.md +18 -18
- package/skills/ti-expert/references/alloy-structure.md +21 -21
- package/skills/ti-expert/references/anti-patterns.md +15 -15
- package/skills/ti-expert/references/cli-expert.md +15 -15
- package/skills/ti-expert/references/code-conventions.md +38 -38
- package/skills/ti-expert/references/contracts.md +8 -8
- package/skills/ti-expert/references/controller-patterns.md +14 -14
- package/skills/ti-expert/references/error-handling.md +11 -11
- package/skills/ti-expert/references/examples.md +12 -12
- package/skills/ti-expert/references/migration-patterns.md +24 -24
- package/skills/ti-expert/references/patterns.md +10 -10
- package/skills/ti-expert/references/performance-listview.md +16 -16
- package/skills/ti-expert/references/performance-optimization.md +41 -41
- package/skills/ti-expert/references/security-device.md +22 -22
- package/skills/ti-expert/references/security-fundamentals.md +19 -19
- package/skills/ti-expert/references/state-management.md +33 -33
- package/skills/ti-expert/references/testing-e2e-ci.md +25 -25
- package/skills/ti-expert/references/testing-unit.md +24 -24
- package/skills/ti-expert/references/theming.md +15 -15
- package/skills/ti-guides/SKILL.md +58 -60
- package/skills/ti-guides/references/advanced-data-and-images.md +33 -33
- package/skills/ti-guides/references/android-manifest.md +15 -15
- package/skills/ti-guides/references/app-distribution.md +70 -166
- package/skills/ti-guides/references/application-frameworks.md +96 -114
- package/skills/ti-guides/references/cli-reference.md +294 -294
- package/skills/ti-guides/references/coding-best-practices.md +42 -33
- package/skills/ti-guides/references/commonjs-advanced.md +57 -51
- package/skills/ti-guides/references/hello-world.md +36 -36
- package/skills/ti-guides/references/hyperloop-native-access.md +66 -66
- package/skills/ti-guides/references/javascript-primer.md +83 -101
- package/skills/ti-guides/references/reserved-words.md +9 -9
- package/skills/ti-guides/references/resources.md +75 -83
- package/skills/ti-guides/references/style-and-conventions.md +35 -28
- package/skills/ti-guides/references/tiapp-config.md +110 -74
- package/skills/ti-howtos/SKILL.md +88 -92
- package/skills/ti-howtos/references/android-platform-deep-dives.md +104 -104
- package/skills/ti-howtos/references/automation-fastlane-appium.md +39 -39
- package/skills/ti-howtos/references/buffer-codec-streams.md +60 -60
- package/skills/ti-howtos/references/cross-platform-development.md +115 -136
- package/skills/ti-howtos/references/debugging-profiling.md +167 -181
- package/skills/ti-howtos/references/extending-titanium.md +121 -121
- package/skills/ti-howtos/references/google-maps-v2.md +84 -82
- package/skills/ti-howtos/references/ios-map-kit.md +65 -60
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +123 -123
- package/skills/ti-howtos/references/local-data-sources.md +79 -78
- package/skills/ti-howtos/references/location-and-maps.md +116 -120
- package/skills/ti-howtos/references/media-apis.md +87 -86
- package/skills/ti-howtos/references/notification-services.md +250 -260
- package/skills/ti-howtos/references/remote-data-sources.md +98 -93
- package/skills/ti-howtos/references/tutorials.md +226 -216
- package/skills/ti-howtos/references/using-modules.md +73 -102
- package/skills/ti-howtos/references/web-content-integration.md +101 -103
- package/skills/ti-howtos/references/webpack-build-pipeline.md +52 -44
- package/skills/ti-ui/SKILL.md +85 -85
- package/skills/ti-ui/references/accessibility-deep-dive.md +57 -57
- package/skills/ti-ui/references/animation-and-matrices.md +79 -79
- package/skills/ti-ui/references/application-structures.md +96 -99
- package/skills/ti-ui/references/custom-fonts-styling.md +99 -99
- package/skills/ti-ui/references/event-handling.md +58 -58
- package/skills/ti-ui/references/gestures.md +62 -64
- package/skills/ti-ui/references/icons-and-splash-screens.md +88 -88
- package/skills/ti-ui/references/layouts-and-positioning.md +87 -97
- package/skills/ti-ui/references/listviews-and-performance.md +107 -107
- package/skills/ti-ui/references/orientation.md +87 -88
- package/skills/ti-ui/references/platform-ui-android.md +87 -81
- package/skills/ti-ui/references/platform-ui-ios.md +63 -61
- package/skills/ti-ui/references/scrolling-views.md +29 -29
- package/skills/ti-ui/references/tableviews.md +56 -56
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Performance
|
|
1
|
+
# Performance optimization: bridge, memory, animation & timing
|
|
2
2
|
|
|
3
|
-
## Bridge
|
|
3
|
+
## Bridge optimization
|
|
4
4
|
|
|
5
|
-
### Minimize
|
|
5
|
+
### Minimize bridge crossings
|
|
6
6
|
|
|
7
7
|
Every JavaScript -> Native call crosses a bridge. Minimize these:
|
|
8
8
|
|
|
@@ -17,7 +17,7 @@ const displayCaps = Ti.Platform.displayCaps
|
|
|
17
17
|
const { platformWidth, platformHeight, dpi } = displayCaps
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
### Batch UI
|
|
20
|
+
### Batch UI updates
|
|
21
21
|
|
|
22
22
|
```javascript
|
|
23
23
|
// BAD: Multiple bridge crossings
|
|
@@ -35,7 +35,7 @@ $.nameLabel.applyProperties({
|
|
|
35
35
|
})
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
### Use TSS
|
|
38
|
+
### Use TSS files instead of inline attributes
|
|
39
39
|
|
|
40
40
|
```xml
|
|
41
41
|
<!-- BAD: Inline styling = scattered and hard to maintain -->
|
|
@@ -50,9 +50,9 @@ $.nameLabel.applyProperties({
|
|
|
50
50
|
"#helloLabel": { width: 200, height: 40, color: '#000', font: { fontSize: 16 } }
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
## Memory
|
|
53
|
+
## Memory management
|
|
54
54
|
|
|
55
|
-
### Controller
|
|
55
|
+
### Controller cleanup pattern
|
|
56
56
|
|
|
57
57
|
```javascript
|
|
58
58
|
// controllers/detail.js
|
|
@@ -106,7 +106,7 @@ function cleanup() {
|
|
|
106
106
|
$.cleanup = cleanup
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
## Image
|
|
109
|
+
## Image memory management
|
|
110
110
|
|
|
111
111
|
```javascript
|
|
112
112
|
// lib/services/imageManager.js
|
|
@@ -150,7 +150,7 @@ exports.ImageManager = {
|
|
|
150
150
|
}
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
## Lazy
|
|
153
|
+
## Lazy loading pattern
|
|
154
154
|
|
|
155
155
|
```javascript
|
|
156
156
|
// controllers/feed/list.js
|
|
@@ -207,7 +207,7 @@ function cleanup() {
|
|
|
207
207
|
$.cleanup = cleanup
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
-
## Database
|
|
210
|
+
## Database performance
|
|
211
211
|
|
|
212
212
|
```javascript
|
|
213
213
|
// lib/services/database.js
|
|
@@ -284,7 +284,7 @@ exports.DB = {
|
|
|
284
284
|
}
|
|
285
285
|
```
|
|
286
286
|
|
|
287
|
-
## Performance
|
|
287
|
+
## Performance monitoring
|
|
288
288
|
|
|
289
289
|
```javascript
|
|
290
290
|
// lib/services/perfMonitor.js
|
|
@@ -343,9 +343,9 @@ renderUsers(users)
|
|
|
343
343
|
measure.end()
|
|
344
344
|
```
|
|
345
345
|
|
|
346
|
-
## Animation
|
|
346
|
+
## Animation performance
|
|
347
347
|
|
|
348
|
-
### 60fps
|
|
348
|
+
### 60fps animation rules
|
|
349
349
|
|
|
350
350
|
```javascript
|
|
351
351
|
// Rule 1: Use native animations (not JavaScript intervals)
|
|
@@ -406,7 +406,7 @@ fadeIn($.modal, () => {
|
|
|
406
406
|
})
|
|
407
407
|
```
|
|
408
408
|
|
|
409
|
-
## Hardware-
|
|
409
|
+
## Hardware-accelerated properties
|
|
410
410
|
|
|
411
411
|
```javascript
|
|
412
412
|
// These properties are GPU-accelerated (fast):
|
|
@@ -438,7 +438,7 @@ const badAnimation = Ti.UI.createAnimation({
|
|
|
438
438
|
})
|
|
439
439
|
```
|
|
440
440
|
|
|
441
|
-
## Animation
|
|
441
|
+
## Animation cleanup
|
|
442
442
|
|
|
443
443
|
```javascript
|
|
444
444
|
// Always remove animation listeners
|
|
@@ -471,9 +471,9 @@ function cleanup() {
|
|
|
471
471
|
$.cleanup = cleanup
|
|
472
472
|
```
|
|
473
473
|
|
|
474
|
-
## Debouncing and
|
|
474
|
+
## Debouncing and throttling
|
|
475
475
|
|
|
476
|
-
### Debounce
|
|
476
|
+
### Debounce pattern
|
|
477
477
|
|
|
478
478
|
Use when you want to wait for the user to stop an action before processing.
|
|
479
479
|
|
|
@@ -517,7 +517,7 @@ function cleanup() {
|
|
|
517
517
|
}
|
|
518
518
|
```
|
|
519
519
|
|
|
520
|
-
### Throttle
|
|
520
|
+
### Throttle pattern
|
|
521
521
|
|
|
522
522
|
Use when you want to limit how often a function can run.
|
|
523
523
|
|
|
@@ -572,18 +572,18 @@ function cleanup() {
|
|
|
572
572
|
}
|
|
573
573
|
```
|
|
574
574
|
|
|
575
|
-
### Common
|
|
575
|
+
### Common use cases
|
|
576
576
|
|
|
577
|
-
| Pattern
|
|
577
|
+
| Pattern | Use Case | Delay |
|
|
578
578
|
| -------- | ---------------- | ------------ |
|
|
579
|
-
| Debounce | Search input
|
|
580
|
-
| Debounce | Auto-save
|
|
581
|
-
| Debounce | Window resize
|
|
582
|
-
| Throttle | Scroll events
|
|
579
|
+
| Debounce | Search input | 300ms |
|
|
580
|
+
| Debounce | Auto-save | 1000ms |
|
|
581
|
+
| Debounce | Window resize | 150ms |
|
|
582
|
+
| Throttle | Scroll events | 50-100ms |
|
|
583
583
|
| Throttle | Mouse/touch move | 16ms (60fps) |
|
|
584
|
-
| Throttle | API polling
|
|
584
|
+
| Throttle | API polling | 5000ms+ |
|
|
585
585
|
|
|
586
|
-
### Combined
|
|
586
|
+
### Combined pattern for real-time + final
|
|
587
587
|
|
|
588
588
|
```javascript
|
|
589
589
|
// Show immediate feedback while typing, but only search when done
|
|
@@ -620,20 +620,20 @@ function cleanup() {
|
|
|
620
620
|
}
|
|
621
621
|
```
|
|
622
622
|
|
|
623
|
-
## Performance
|
|
623
|
+
## Performance checklist
|
|
624
624
|
|
|
625
|
-
| Area
|
|
625
|
+
| Area | Check |
|
|
626
626
|
| ------------- | --------------------------------------- |
|
|
627
|
-
| **Bridge**
|
|
628
|
-
| **Bridge**
|
|
629
|
-
| **Bridge**
|
|
630
|
-
| **Memory**
|
|
631
|
-
| **Memory**
|
|
632
|
-
| **Memory**
|
|
633
|
-
| **Database**
|
|
634
|
-
| **Database**
|
|
635
|
-
| **Database**
|
|
636
|
-
| **Animation** | Using native animations, not intervals
|
|
637
|
-
| **Animation** | GPU-accelerated properties preferred
|
|
638
|
-
| **Timing**
|
|
639
|
-
| **Timing**
|
|
627
|
+
| **Bridge** | Cached Ti.Platform properties |
|
|
628
|
+
| **Bridge** | Using applyProperties for updates |
|
|
629
|
+
| **Bridge** | TSS styles instead of inline attributes |
|
|
630
|
+
| **Memory** | All global listeners cleaned up |
|
|
631
|
+
| **Memory** | Heavy objects nulled in cleanup |
|
|
632
|
+
| **Memory** | Images resized appropriately |
|
|
633
|
+
| **Database** | Using transactions for batch ops |
|
|
634
|
+
| **Database** | Indexes on frequently queried columns |
|
|
635
|
+
| **Database** | ResultSets and DB handles closed |
|
|
636
|
+
| **Animation** | Using native animations, not intervals |
|
|
637
|
+
| **Animation** | GPU-accelerated properties preferred |
|
|
638
|
+
| **Timing** | Debounce on search/input |
|
|
639
|
+
| **Timing** | Throttle on scroll/touch events |
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Device
|
|
1
|
+
# Device security: biometrics, deep links & integrity
|
|
2
2
|
|
|
3
|
-
## Biometric
|
|
3
|
+
## Biometric authentication
|
|
4
4
|
|
|
5
|
-
### Using ti.identity
|
|
5
|
+
### Using ti.identity module
|
|
6
6
|
|
|
7
7
|
```javascript
|
|
8
8
|
// lib/services/biometricService.js
|
|
@@ -83,7 +83,7 @@ exports.BiometricService = {
|
|
|
83
83
|
}
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
## Biometric
|
|
86
|
+
## Biometric login flow
|
|
87
87
|
|
|
88
88
|
```javascript
|
|
89
89
|
// controllers/auth/login.js
|
|
@@ -148,9 +148,9 @@ async function onLoginSuccess(user) {
|
|
|
148
148
|
}
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
## Deep
|
|
151
|
+
## Deep link security
|
|
152
152
|
|
|
153
|
-
### Validating
|
|
153
|
+
### Validating deep links
|
|
154
154
|
|
|
155
155
|
```javascript
|
|
156
156
|
// lib/services/deepLinkService.js
|
|
@@ -311,7 +311,7 @@ exports.DeepLinkService = {
|
|
|
311
311
|
}
|
|
312
312
|
```
|
|
313
313
|
|
|
314
|
-
## Registering
|
|
314
|
+
## Registering deep link handler
|
|
315
315
|
|
|
316
316
|
```javascript
|
|
317
317
|
// alloy.js
|
|
@@ -346,9 +346,9 @@ if (OS_ANDROID) {
|
|
|
346
346
|
}
|
|
347
347
|
```
|
|
348
348
|
|
|
349
|
-
## Jailbreak/Root
|
|
349
|
+
## Jailbreak/Root detection
|
|
350
350
|
|
|
351
|
-
### Detection
|
|
351
|
+
### Detection service
|
|
352
352
|
|
|
353
353
|
```javascript
|
|
354
354
|
// lib/services/securityService.js
|
|
@@ -528,7 +528,7 @@ exports.SecurityService = {
|
|
|
528
528
|
}
|
|
529
529
|
```
|
|
530
530
|
|
|
531
|
-
## Integrating
|
|
531
|
+
## Integrating security checks
|
|
532
532
|
|
|
533
533
|
```javascript
|
|
534
534
|
// alloy.js
|
|
@@ -548,17 +548,17 @@ setInterval(() => {
|
|
|
548
548
|
}, 5 * 60 * 1000) // Every 5 minutes
|
|
549
549
|
```
|
|
550
550
|
|
|
551
|
-
## Security
|
|
551
|
+
## Security checklist
|
|
552
552
|
|
|
553
|
-
| Category
|
|
553
|
+
| Category | Check | Implementation |
|
|
554
554
|
| -------------- | -------------------------- | ------------------------ |
|
|
555
|
-
| **Biometrics** | Use ti.identity for auth
|
|
556
|
-
| **Biometrics** | Never store biometric data | System handles storage
|
|
557
|
-
| **Biometrics** | Fallback to password
|
|
558
|
-
| **Deep Links** | Whitelist allowed schemes
|
|
559
|
-
| **Deep Links** | Whitelist allowed hosts
|
|
560
|
-
| **Deep Links** | Sanitize all parameters
|
|
561
|
-
| **Deep Links** | Check auth requirements
|
|
562
|
-
| **Integrity**
|
|
563
|
-
| **Integrity**
|
|
564
|
-
| **Integrity**
|
|
555
|
+
| **Biometrics** | Use ti.identity for auth | BiometricService wrapper |
|
|
556
|
+
| **Biometrics** | Never store biometric data | System handles storage |
|
|
557
|
+
| **Biometrics** | Fallback to password | Always offer alternative |
|
|
558
|
+
| **Deep Links** | Whitelist allowed schemes | ALLOWED_SCHEMES constant |
|
|
559
|
+
| **Deep Links** | Whitelist allowed hosts | ALLOWED_HOSTS constant |
|
|
560
|
+
| **Deep Links** | Sanitize all parameters | _sanitizeParams() |
|
|
561
|
+
| **Deep Links** | Check auth requirements | requiresAuth per route |
|
|
562
|
+
| **Integrity** | Check for jailbreak/root | checkDeviceIntegrity() |
|
|
563
|
+
| **Integrity** | Define security policy | block/restrict/warn |
|
|
564
|
+
| **Integrity** | Log security events | Always log compromises |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Security
|
|
1
|
+
# Security fundamentals for Titanium mobile apps
|
|
2
2
|
|
|
3
|
-
## Token
|
|
3
|
+
## Token storage strategy
|
|
4
4
|
|
|
5
5
|
**NEVER store tokens in:** `Ti.App.Properties` (plaintext), localStorage, or files.
|
|
6
6
|
|
|
@@ -56,7 +56,7 @@ exports.TokenStorage = {
|
|
|
56
56
|
}
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
## Certificate
|
|
59
|
+
## Certificate pinning
|
|
60
60
|
|
|
61
61
|
Prevent man-in-the-middle attacks by pinning SSL certificates:
|
|
62
62
|
|
|
@@ -100,7 +100,7 @@ exports.createPinnedClient = function() {
|
|
|
100
100
|
</ti:app>
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
## Data
|
|
103
|
+
## Data encryption at rest
|
|
104
104
|
|
|
105
105
|
```javascript
|
|
106
106
|
// lib/services/encryption.js
|
|
@@ -151,7 +151,7 @@ module.exports = class SecureCache {
|
|
|
151
151
|
}
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
-
## Secure HTTP
|
|
154
|
+
## Secure HTTP communication
|
|
155
155
|
|
|
156
156
|
```javascript
|
|
157
157
|
// lib/api/secureClient.js
|
|
@@ -205,7 +205,7 @@ exports.createSecureClient = function(baseUrl) {
|
|
|
205
205
|
}
|
|
206
206
|
```
|
|
207
207
|
|
|
208
|
-
## Authentication
|
|
208
|
+
## Authentication token refresh pattern
|
|
209
209
|
|
|
210
210
|
```javascript
|
|
211
211
|
// lib/services/authService.js
|
|
@@ -238,7 +238,7 @@ function scheduleTokenRefresh(expiresIn) {
|
|
|
238
238
|
}
|
|
239
239
|
```
|
|
240
240
|
|
|
241
|
-
## Input
|
|
241
|
+
## Input validation
|
|
242
242
|
|
|
243
243
|
```javascript
|
|
244
244
|
// lib/services/validator.js
|
|
@@ -268,17 +268,17 @@ exports.Validator = {
|
|
|
268
268
|
}
|
|
269
269
|
```
|
|
270
270
|
|
|
271
|
-
##
|
|
271
|
+
## Owasp mobile security checklist
|
|
272
272
|
|
|
273
|
-
| Category
|
|
273
|
+
| Category | Check | Implementation |
|
|
274
274
|
| -------------------- | --------------------------- | ---------------------------------- |
|
|
275
|
-
| **Data Storage**
|
|
276
|
-
| **Data Storage**
|
|
277
|
-
| **Communication**
|
|
278
|
-
| **Communication**
|
|
279
|
-
| **Authentication**
|
|
280
|
-
| **Authentication**
|
|
281
|
-
| **Input Validation** | Server-side validation
|
|
282
|
-
| **Input Validation** | Sanitize user input
|
|
283
|
-
| **Cryptography**
|
|
284
|
-
| **Cryptography**
|
|
275
|
+
| **Data Storage** | Credentials stored securely | Keychain/KeyStore for tokens |
|
|
276
|
+
| **Data Storage** | Sensitive data encrypted | AES-256 for cached data |
|
|
277
|
+
| **Communication** | HTTPS only | `validatesSecureCertificate: true` |
|
|
278
|
+
| **Communication** | Certificate pinning | SSL pinning enabled |
|
|
279
|
+
| **Authentication** | Token refresh | Auto-refresh before expiry |
|
|
280
|
+
| **Authentication** | Session timeout | Auto-logout after inactivity |
|
|
281
|
+
| **Input Validation** | Server-side validation | Never trust client input |
|
|
282
|
+
| **Input Validation** | Sanitize user input | Remove XSS patterns |
|
|
283
|
+
| **Cryptography** | No hardcoded keys | Keys from secure storage |
|
|
284
|
+
| **Cryptography** | Use standard algorithms | AES-256, SHA-256 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# State
|
|
1
|
+
# State management patterns
|
|
2
2
|
|
|
3
|
-
## The
|
|
3
|
+
## The problem
|
|
4
4
|
|
|
5
5
|
As apps grow, state gets scattered:
|
|
6
6
|
- `Alloy.Collections` scattered across controllers
|
|
@@ -13,7 +13,7 @@ This leads to:
|
|
|
13
13
|
- Inconsistent UI updates
|
|
14
14
|
- Difficult debugging
|
|
15
15
|
|
|
16
|
-
## Solution:
|
|
16
|
+
## Solution: centralized state store
|
|
17
17
|
|
|
18
18
|
Create a single source of truth using Backbone.Events:
|
|
19
19
|
|
|
@@ -76,7 +76,7 @@ class StateStore {
|
|
|
76
76
|
exports.appStore = new StateStore()
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
## State
|
|
79
|
+
## State store usage
|
|
80
80
|
|
|
81
81
|
### Initialization in alloy.js
|
|
82
82
|
|
|
@@ -101,7 +101,7 @@ function initAppStore() {
|
|
|
101
101
|
initAppStore()
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
### Using
|
|
104
|
+
### Using state in controllers
|
|
105
105
|
|
|
106
106
|
```javascript
|
|
107
107
|
// controllers/home/index.js
|
|
@@ -139,7 +139,7 @@ function cleanup() {
|
|
|
139
139
|
}
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
-
### Updating
|
|
142
|
+
### Updating state from services
|
|
143
143
|
|
|
144
144
|
```javascript
|
|
145
145
|
// lib/services/authService.js
|
|
@@ -189,7 +189,7 @@ exports.logout = async function() {
|
|
|
189
189
|
}
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
-
## Service
|
|
192
|
+
## Service layer state caching
|
|
193
193
|
|
|
194
194
|
Services can maintain their own cached state:
|
|
195
195
|
|
|
@@ -229,7 +229,7 @@ class UserService {
|
|
|
229
229
|
exports.userService = new UserService()
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
-
## Collections vs
|
|
232
|
+
## Collections vs state store
|
|
233
233
|
|
|
234
234
|
**Use Alloy.Collections when:**
|
|
235
235
|
- Data is list-based (users, items, messages)
|
|
@@ -254,7 +254,7 @@ Alloy.Collections.users.fetch({
|
|
|
254
254
|
})
|
|
255
255
|
```
|
|
256
256
|
|
|
257
|
-
## State
|
|
257
|
+
## State synchronization pattern
|
|
258
258
|
|
|
259
259
|
When state needs to sync with server:
|
|
260
260
|
|
|
@@ -278,19 +278,19 @@ Ti.App.addEventListener('resume', () => {
|
|
|
278
278
|
})
|
|
279
279
|
```
|
|
280
280
|
|
|
281
|
-
## Anti-
|
|
281
|
+
## Anti-patterns
|
|
282
282
|
|
|
283
|
-
| Anti-Pattern
|
|
283
|
+
| Anti-Pattern | Why It's Bad | Solution |
|
|
284
284
|
| ------------------------------------- | ---------------------------- | ---------------------------------------- |
|
|
285
|
-
| `Ti.App.fireEvent` for state
|
|
286
|
-
| Direct collection mutation
|
|
287
|
-
| State in multiple places
|
|
288
|
-
| Global variables (`Alloy.Globals`)
|
|
289
|
-
| Controller-to-controller direct calls | Tight coupling
|
|
285
|
+
| `Ti.App.fireEvent` for state | No cleanup, memory leaks | Use StateStore with `offChange` |
|
|
286
|
+
| Direct collection mutation | Bypasses reactivity | Use collection methods (`add`, `remove`) |
|
|
287
|
+
| State in multiple places | Inconsistency bugs | Single source of truth |
|
|
288
|
+
| Global variables (`Alloy.Globals`) | No reactivity, hard to track | Use StateStore |
|
|
289
|
+
| Controller-to-controller direct calls | Tight coupling | Use StateStore or events |
|
|
290
290
|
|
|
291
|
-
## Persistence
|
|
291
|
+
## Persistence strategies
|
|
292
292
|
|
|
293
|
-
### Ti.App.Properties (Simple
|
|
293
|
+
### Ti.App.Properties (Simple Main-Value)
|
|
294
294
|
|
|
295
295
|
Best for: User preferences, flags, simple settings.
|
|
296
296
|
|
|
@@ -415,7 +415,7 @@ exports.Database = {
|
|
|
415
415
|
}
|
|
416
416
|
```
|
|
417
417
|
|
|
418
|
-
### Hybrid
|
|
418
|
+
### Hybrid strategy (Recommended)
|
|
419
419
|
|
|
420
420
|
```javascript
|
|
421
421
|
// lib/services/stateStore.js
|
|
@@ -470,20 +470,20 @@ exports.appStore = {
|
|
|
470
470
|
}
|
|
471
471
|
```
|
|
472
472
|
|
|
473
|
-
### Choosing a
|
|
473
|
+
### Choosing a strategy
|
|
474
474
|
|
|
475
|
-
| Data Type
|
|
475
|
+
| Data Type | Strategy | Reason |
|
|
476
476
|
| ------------------ | ------------------- | ---------------------- |
|
|
477
|
-
| User preferences
|
|
478
|
-
| Auth tokens
|
|
479
|
-
| User profile
|
|
480
|
-
| Lists (100+ items) | SQLite
|
|
481
|
-
| Offline queue
|
|
482
|
-
| Cache
|
|
477
|
+
| User preferences | Ti.App.Properties | Simple main-value, fast |
|
|
478
|
+
| Auth tokens | Keychain/KeyStore | Security |
|
|
479
|
+
| User profile | Properties + Secure | Mixed sensitivity |
|
|
480
|
+
| Lists (100+ items) | SQLite | Query, pagination |
|
|
481
|
+
| Offline queue | SQLite | Durability, FIFO |
|
|
482
|
+
| Cache | In-memory + SQLite | Speed + persistence |
|
|
483
483
|
|
|
484
|
-
## State
|
|
484
|
+
## State middleware
|
|
485
485
|
|
|
486
|
-
### Logger
|
|
486
|
+
### Logger middleware
|
|
487
487
|
|
|
488
488
|
```javascript
|
|
489
489
|
// lib/services/stateStore.js
|
|
@@ -569,7 +569,7 @@ appStore
|
|
|
569
569
|
.use(persistMiddleware)
|
|
570
570
|
```
|
|
571
571
|
|
|
572
|
-
### Action-
|
|
572
|
+
### Action-based state updates
|
|
573
573
|
|
|
574
574
|
```javascript
|
|
575
575
|
// lib/services/stateStore.js
|
|
@@ -639,9 +639,9 @@ appStore.dispatch('user/login', { user: userData, token: authToken })
|
|
|
639
639
|
appStore.dispatch('cart/add', { item: product })
|
|
640
640
|
```
|
|
641
641
|
|
|
642
|
-
## State
|
|
642
|
+
## State debugging
|
|
643
643
|
|
|
644
|
-
### Debug
|
|
644
|
+
### Debug helper
|
|
645
645
|
|
|
646
646
|
```javascript
|
|
647
647
|
// lib/services/stateDebug.js
|
|
@@ -723,7 +723,7 @@ const debugMiddleware = (oldState, action, newState) => {
|
|
|
723
723
|
appStore.use(debugMiddleware)
|
|
724
724
|
```
|
|
725
725
|
|
|
726
|
-
### Development
|
|
726
|
+
### Development panel
|
|
727
727
|
|
|
728
728
|
```javascript
|
|
729
729
|
// controllers/debug/stateViewer.js (Development only)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# End-to-
|
|
1
|
+
# End-to-end testing & CI/CD
|
|
2
2
|
|
|
3
|
-
## Appium
|
|
3
|
+
## Appium setup
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
# Install Appium
|
|
@@ -11,7 +11,7 @@ appium driver install xcuitest # iOS
|
|
|
11
11
|
appium driver install uiautomator2 # Android
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
## Appium
|
|
14
|
+
## Appium configuration
|
|
15
15
|
|
|
16
16
|
```javascript
|
|
17
17
|
// e2e/config/capabilities.js
|
|
@@ -34,7 +34,7 @@ exports.android = {
|
|
|
34
34
|
}
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
##
|
|
37
|
+
## Webdriverio integration
|
|
38
38
|
|
|
39
39
|
```javascript
|
|
40
40
|
// e2e/wdio.conf.js
|
|
@@ -72,7 +72,7 @@ exports.config = {
|
|
|
72
72
|
}
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
## E2E
|
|
75
|
+
## E2E test example
|
|
76
76
|
|
|
77
77
|
```javascript
|
|
78
78
|
// e2e/specs/login.spec.js
|
|
@@ -125,7 +125,7 @@ describe('Login Flow', () => {
|
|
|
125
125
|
})
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
-
## Adding
|
|
128
|
+
## Adding accessibility IDs for testing
|
|
129
129
|
|
|
130
130
|
```xml
|
|
131
131
|
<!-- views/auth/login.xml -->
|
|
@@ -145,7 +145,7 @@ if (Alloy.CFG.debug) {
|
|
|
145
145
|
}
|
|
146
146
|
```
|
|
147
147
|
|
|
148
|
-
## Page
|
|
148
|
+
## Page object pattern
|
|
149
149
|
|
|
150
150
|
```javascript
|
|
151
151
|
// e2e/pages/LoginPage.js
|
|
@@ -184,9 +184,9 @@ describe('Login Flow', () => {
|
|
|
184
184
|
})
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
-
## CI/CD
|
|
187
|
+
## CI/CD integration
|
|
188
188
|
|
|
189
|
-
###
|
|
189
|
+
### Github actions workflow
|
|
190
190
|
|
|
191
191
|
```yaml
|
|
192
192
|
# .github/workflows/ci.yml
|
|
@@ -348,7 +348,7 @@ jobs:
|
|
|
348
348
|
path: e2e/screenshots/
|
|
349
349
|
```
|
|
350
350
|
|
|
351
|
-
## Fastlane
|
|
351
|
+
## Fastlane integration
|
|
352
352
|
|
|
353
353
|
```ruby
|
|
354
354
|
# fastlane/Fastfile
|
|
@@ -389,7 +389,7 @@ platform :android do
|
|
|
389
389
|
end
|
|
390
390
|
```
|
|
391
391
|
|
|
392
|
-
## Package.json
|
|
392
|
+
## Package.json scripts
|
|
393
393
|
|
|
394
394
|
```json
|
|
395
395
|
{
|
|
@@ -408,25 +408,25 @@ end
|
|
|
408
408
|
}
|
|
409
409
|
```
|
|
410
410
|
|
|
411
|
-
## Branch
|
|
411
|
+
## Branch protection rules
|
|
412
412
|
|
|
413
413
|
Configure in GitHub repository settings:
|
|
414
414
|
|
|
415
|
-
| Rule
|
|
415
|
+
| Rule | Setting |
|
|
416
416
|
| --------------------------------- | ------------------------------------------ |
|
|
417
|
-
| Require pull request reviews
|
|
418
|
-
| Require status checks
|
|
419
|
-
| Require branches to be up to date | Yes
|
|
420
|
-
| Include administrators
|
|
417
|
+
| Require pull request reviews | 1 approval required |
|
|
418
|
+
| Require status checks | lint, unit-tests, build-ios, build-android |
|
|
419
|
+
| Require branches to be up to date | Yes |
|
|
420
|
+
| Include administrators | Yes |
|
|
421
421
|
|
|
422
|
-
## Testing
|
|
422
|
+
## Testing best practices summary
|
|
423
423
|
|
|
424
|
-
| Area
|
|
424
|
+
| Area | Practice |
|
|
425
425
|
| --------------------- | ------------------------------------------ |
|
|
426
|
-
| **Unit Tests**
|
|
426
|
+
| **Unit Tests** | Test business logic in services/helpers |
|
|
427
427
|
| **Integration Tests** | Test controller flows with mocked services |
|
|
428
|
-
| **E2E Tests**
|
|
429
|
-
| **Coverage**
|
|
430
|
-
| **CI Pipeline**
|
|
431
|
-
| **Artifacts**
|
|
432
|
-
| **Notifications**
|
|
428
|
+
| **E2E Tests** | Test critical user journeys |
|
|
429
|
+
| **Coverage** | Aim for 80%+ on services, 60%+ overall |
|
|
430
|
+
| **CI Pipeline** | Run lint -> unit tests -> build -> E2E |
|
|
431
|
+
| **Artifacts** | Save screenshots on failure |
|
|
432
|
+
| **Notifications** | Slack/email on build failures |
|