native-update 1.4.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +13 -1
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdatePlugin.kt +15 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateWorker.kt +23 -7
- package/android/src/main/java/com/aoneahsan/nativeupdate/LiveUpdatePlugin.kt +152 -4
- package/android/src/main/java/com/aoneahsan/nativeupdate/NativeUpdatePlugin.kt +14 -1
- package/android/src/main/java/com/aoneahsan/nativeupdate/NotificationActionReceiver.kt +10 -1
- package/android/src/main/java/com/aoneahsan/nativeupdate/SecurityManager.kt +18 -18
- package/cli/AGENTS.md +29 -0
- package/cli/CLAUDE.md +51 -0
- package/dist/esm/__tests__/security-enforcement.test.d.ts +1 -0
- package/dist/esm/__tests__/security-enforcement.test.js +95 -0
- package/dist/esm/__tests__/security-enforcement.test.js.map +1 -0
- package/dist/esm/core/config.d.ts +6 -15
- package/dist/esm/core/config.js +1 -4
- package/dist/esm/core/config.js.map +1 -1
- package/dist/esm/core/security.d.ts +11 -3
- package/dist/esm/core/security.js +19 -6
- package/dist/esm/core/security.js.map +1 -1
- package/dist/esm/definitions.d.ts +38 -24
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/firestore/firestore-client.js +4 -0
- package/dist/esm/firestore/firestore-client.js.map +1 -1
- package/dist/esm/firestore/schema.d.ts +2 -0
- package/dist/esm/firestore/schema.js.map +1 -1
- package/dist/esm/index.d.ts +1 -2
- package/dist/esm/index.js +0 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/live-update/download-manager.d.ts +36 -5
- package/dist/esm/live-update/download-manager.js +61 -22
- package/dist/esm/live-update/download-manager.js.map +1 -1
- package/dist/esm/live-update/update-manager.d.ts +12 -1
- package/dist/esm/live-update/update-manager.js +38 -10
- package/dist/esm/live-update/update-manager.js.map +1 -1
- package/dist/esm/live-update/version-manager.d.ts +9 -0
- package/dist/esm/live-update/version-manager.js +40 -0
- package/dist/esm/live-update/version-manager.js.map +1 -1
- package/dist/esm/plugin.js +95 -175
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/web.d.ts +18 -1
- package/dist/esm/web.js +69 -24
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +1 -1
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.esm.js +1 -1
- package/dist/plugin.esm.js.map +1 -1
- package/dist/plugin.js +2 -2
- package/dist/plugin.js.map +1 -1
- package/docs/AGENTS.md +38 -0
- package/docs/CHANGELOG.md +167 -0
- package/docs/CLAUDE.md +101 -0
- package/docs/MIGRATION.md +87 -0
- package/docs/README.md +13 -2
- package/docs/deployment/HOSTINGER_DEPLOY.md +329 -0
- package/docs/features/laravel-nova-backend/ASSESSMENT-SUMMARY.md +96 -0
- package/docs/features/laravel-nova-backend/IMPLEMENTATION-PLAN.md +504 -0
- package/docs/features/laravel-nova-backend/credentials.ignore.md +34 -0
- package/docs/features/laravel-nova-backend/progress-tracker.json +184 -0
- package/docs/guides/no-cost-backend-implementation-plan.md +77 -0
- package/docs/guides/no-cost-firestore-google-drive-backend.md +60 -0
- package/docs/project-knowledge-base/01-system-overview.md +218 -0
- package/docs/project-knowledge-base/02-routes-pages-forms-users.md +346 -0
- package/docs/project-knowledge-base/03-tech-stack-modules-services.md +347 -0
- package/docs/project-knowledge-base/04-data-models-integrations.md +307 -0
- package/docs/project-knowledge-base/05-docs-corpus-inventory.md +193 -0
- package/docs/project-knowledge-base/06-operations-testing-legal-content.md +170 -0
- package/docs/project-knowledge-base/README.md +90 -0
- package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-16.md +454 -0
- package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-24.md +66 -0
- package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-25.md +67 -0
- package/docs/seo-aeo-rules.json +3043 -0
- package/docs/tracking/seo-checklist-tracker.json +333 -0
- package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +50 -6
- package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +238 -8
- package/ios/Plugin/NativeUpdatePlugin.swift +8 -0
- package/ios/Plugin/Security/SecurityManager.swift +13 -14
- package/package.json +31 -32
- package/docs/play-console-rejection-rules.json +0 -428
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
{
|
|
2
|
+
"project": "native-update",
|
|
3
|
+
"projectUrl": "https://nativeupdate.aoneahsan.com",
|
|
4
|
+
"projectDescription": "Capacitor plugin for OTA updates, app store updates & in-app reviews",
|
|
5
|
+
"createdAt": "2026-04-10",
|
|
6
|
+
"lastUpdated": "2026-04-10",
|
|
7
|
+
"summary": {
|
|
8
|
+
"totalItems": 47,
|
|
9
|
+
"completed": 14,
|
|
10
|
+
"inProgress": 0,
|
|
11
|
+
"pending": 22,
|
|
12
|
+
"notApplicable": 0,
|
|
13
|
+
"requiresDeployment": 11
|
|
14
|
+
},
|
|
15
|
+
"phases": {
|
|
16
|
+
"phase1_technical_foundation": {
|
|
17
|
+
"name": "Phase 1: Technical Foundation",
|
|
18
|
+
"description": "Core technical SEO setup that must be done first",
|
|
19
|
+
"items": [
|
|
20
|
+
{
|
|
21
|
+
"id": "P1-01",
|
|
22
|
+
"task": "Google Search Console - Add property, verify via HTML meta tag or DNS TXT, submit sitemap.xml",
|
|
23
|
+
"status": "requires_deployment",
|
|
24
|
+
"notes": "Must deploy first, then verify at search.google.com/search-console",
|
|
25
|
+
"implementedAt": null
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "P1-02",
|
|
29
|
+
"task": "Bing Webmaster Tools - Add site, verify via meta tag, submit sitemap.xml, import from GSC",
|
|
30
|
+
"status": "requires_deployment",
|
|
31
|
+
"notes": "bing.com/webmasters - has auto-import from Google Search Console",
|
|
32
|
+
"implementedAt": null
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "P1-03",
|
|
36
|
+
"task": "Yandex Webmaster - Add site, verify via meta tag, submit sitemap.xml",
|
|
37
|
+
"status": "requires_deployment",
|
|
38
|
+
"notes": "webmaster.yandex.com",
|
|
39
|
+
"implementedAt": null
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "P1-04",
|
|
43
|
+
"task": "Sitemap.xml - Ensure valid sitemap exists at /sitemap.xml with all public pages",
|
|
44
|
+
"status": "completed",
|
|
45
|
+
"notes": "Cleaned up: removed internal docs (reports, trackers, plans), login/signup. Now 62 clean public URLs.",
|
|
46
|
+
"implementedAt": "2026-04-10"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "P1-05",
|
|
50
|
+
"task": "robots.txt - Ensure it exists and points to sitemap with correct project URL",
|
|
51
|
+
"status": "completed",
|
|
52
|
+
"notes": "Already exists with AI crawler allowlisting and correct sitemap URL",
|
|
53
|
+
"implementedAt": "2026-03-27"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "P1-06",
|
|
57
|
+
"task": "SSL Certificate - All pages must be HTTPS",
|
|
58
|
+
"status": "completed",
|
|
59
|
+
"notes": "Already served via HTTPS on nativeupdate.aoneahsan.com",
|
|
60
|
+
"implementedAt": "2025-12-27"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "P1-07",
|
|
64
|
+
"task": "Mobile Responsive - Test at search.google.com/test/mobile-friendly",
|
|
65
|
+
"status": "requires_deployment",
|
|
66
|
+
"notes": "Deploy then test. Site uses Tailwind CSS with responsive design.",
|
|
67
|
+
"implementedAt": null
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "P1-08",
|
|
71
|
+
"task": "Page Speed - Test at pagespeed.web.dev, aim for 90+ mobile",
|
|
72
|
+
"status": "requires_deployment",
|
|
73
|
+
"notes": "Deploy then test. Optimize based on results.",
|
|
74
|
+
"implementedAt": null
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "P1-09",
|
|
78
|
+
"task": "Core Web Vitals - Check in GSC after a few weeks. LCP < 2.5s, FID < 100ms, CLS < 0.1",
|
|
79
|
+
"status": "requires_deployment",
|
|
80
|
+
"notes": "Needs GSC data accumulation over weeks",
|
|
81
|
+
"implementedAt": null
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"phase2_on_page_seo": {
|
|
86
|
+
"name": "Phase 2: On-Page SEO",
|
|
87
|
+
"description": "Per-page SEO optimization for every public page",
|
|
88
|
+
"items": [
|
|
89
|
+
{
|
|
90
|
+
"id": "P2-01",
|
|
91
|
+
"task": "Title Tags - Every page needs unique <title> under 60 chars",
|
|
92
|
+
"status": "completed",
|
|
93
|
+
"notes": "usePageSEO hook applied to all 14 public pages with unique titles",
|
|
94
|
+
"implementedAt": "2026-04-10"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "P2-02",
|
|
98
|
+
"task": "Meta Descriptions - Every page needs unique <meta description> under 155 chars",
|
|
99
|
+
"status": "completed",
|
|
100
|
+
"notes": "usePageSEO hook sets per-page descriptions on all 14 public pages",
|
|
101
|
+
"implementedAt": "2026-04-10"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"id": "P2-03",
|
|
105
|
+
"task": "H1 Tags - One H1 per page matching the page topic",
|
|
106
|
+
"status": "completed",
|
|
107
|
+
"notes": "Verified: all pages have exactly one H1 tag. Hidden SEO div also has H1 for crawlers.",
|
|
108
|
+
"implementedAt": "2026-04-10"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"id": "P2-04",
|
|
112
|
+
"task": "H2/H3 Structure - Logical heading hierarchy on every page",
|
|
113
|
+
"status": "completed",
|
|
114
|
+
"notes": "Pages use proper H1->H2->H3 hierarchy. Hidden SEO div has structured headings.",
|
|
115
|
+
"implementedAt": "2026-04-10"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"id": "P2-05",
|
|
119
|
+
"task": "Image Alt Text - Every image needs descriptive alt text",
|
|
120
|
+
"status": "pending",
|
|
121
|
+
"notes": "Need to audit all img/svg elements across pages for alt text",
|
|
122
|
+
"implementedAt": null
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "P2-06",
|
|
126
|
+
"task": "Internal Linking - Cross-link related pages (features->docs, pricing->features, etc.)",
|
|
127
|
+
"status": "pending",
|
|
128
|
+
"notes": "Pages have some CTAs but need more cross-linking for SEO juice",
|
|
129
|
+
"implementedAt": null
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"id": "P2-07",
|
|
133
|
+
"task": "Canonical URLs - Add <link rel=canonical> per page to prevent duplicates",
|
|
134
|
+
"status": "completed",
|
|
135
|
+
"notes": "usePageSEO hook sets per-page canonical URL on every page dynamically",
|
|
136
|
+
"implementedAt": "2026-04-10"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"id": "P2-08",
|
|
140
|
+
"task": "Structured Data / Schema Markup - JSON-LD per page type (WebApplication, FAQPage, Article, BreadcrumbList)",
|
|
141
|
+
"status": "completed",
|
|
142
|
+
"notes": "BreadcrumbList auto-generated per page via usePageSEO. SoftwareApplication, FAQPage (10 Q&A), WebSite, Organization in postbuild.",
|
|
143
|
+
"implementedAt": "2026-04-10"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"id": "P2-09",
|
|
147
|
+
"task": "Open Graph tags - Per-page og:title, og:description, og:url, og:image",
|
|
148
|
+
"status": "completed",
|
|
149
|
+
"notes": "usePageSEO hook sets per-page OG tags on all pages",
|
|
150
|
+
"implementedAt": "2026-04-10"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": "P2-10",
|
|
154
|
+
"task": "Twitter Card tags - Per-page twitter:title, twitter:description",
|
|
155
|
+
"status": "completed",
|
|
156
|
+
"notes": "usePageSEO hook sets per-page Twitter Card tags on all pages",
|
|
157
|
+
"implementedAt": "2026-04-10"
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
"phase3_content_seo": {
|
|
162
|
+
"name": "Phase 3: Content SEO",
|
|
163
|
+
"description": "Content strategy for long-tail keywords and organic traffic",
|
|
164
|
+
"items": [
|
|
165
|
+
{
|
|
166
|
+
"id": "P3-01",
|
|
167
|
+
"task": "Blog section - Create blog route and infrastructure for SEO content",
|
|
168
|
+
"status": "pending",
|
|
169
|
+
"notes": "No blog exists yet. Need /blog route with markdown-based posts.",
|
|
170
|
+
"implementedAt": null
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"id": "P3-02",
|
|
174
|
+
"task": "Blog Posts - Write 5-10 initial posts targeting long-tail keywords",
|
|
175
|
+
"status": "pending",
|
|
176
|
+
"notes": "Topics: 'how to deploy OTA updates capacitor', 'capacitor vs codepush', 'mobile app update strategies', etc.",
|
|
177
|
+
"implementedAt": null
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"id": "P3-03",
|
|
181
|
+
"task": "Keyword Research - Identify target keywords using free tools",
|
|
182
|
+
"status": "pending",
|
|
183
|
+
"notes": "Google Keyword Planner, Ubersuggest, AnswerThePublic, Google Autocomplete",
|
|
184
|
+
"implementedAt": null
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"id": "P3-04",
|
|
188
|
+
"task": "FAQ Sections - Add visible FAQ with schema on key pages (home, features, pricing, docs)",
|
|
189
|
+
"status": "pending",
|
|
190
|
+
"notes": "FAQ schema exists in postbuild (expanded to 10 Q&A) but no visible FAQ sections on pages yet",
|
|
191
|
+
"implementedAt": null
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"id": "P3-05",
|
|
195
|
+
"task": "Long-form feature descriptions - 300-500 words of unique content per feature page",
|
|
196
|
+
"status": "pending",
|
|
197
|
+
"notes": "Features page exists but may need more descriptive content per feature",
|
|
198
|
+
"implementedAt": null
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
},
|
|
202
|
+
"phase4_niche_seo": {
|
|
203
|
+
"name": "Phase 4: Niche & Competitive SEO",
|
|
204
|
+
"description": "Niche-specific and competitive positioning content",
|
|
205
|
+
"items": [
|
|
206
|
+
{
|
|
207
|
+
"id": "P4-01",
|
|
208
|
+
"task": "Capacitor-specific keywords - Target 'capacitor ota updates', 'capacitor live updates plugin', 'capacitor code push alternative'",
|
|
209
|
+
"status": "pending",
|
|
210
|
+
"notes": "These are the primary niche keywords for this product",
|
|
211
|
+
"implementedAt": null
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"id": "P4-02",
|
|
215
|
+
"task": "Comparison blog posts - 'Native Update vs CodePush', 'Native Update vs Capgo', 'Best Capacitor OTA plugins 2026'",
|
|
216
|
+
"status": "pending",
|
|
217
|
+
"notes": "Create honest comparison content highlighting strengths",
|
|
218
|
+
"implementedAt": null
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"id": "P4-03",
|
|
222
|
+
"task": "Feature-specific landing content - Each feature (OTA, app updates, reviews) should have rich descriptive content",
|
|
223
|
+
"status": "pending",
|
|
224
|
+
"notes": "Dedicated feature pages exist in /docs/features/ but marketing pages need richer content",
|
|
225
|
+
"implementedAt": null
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
},
|
|
229
|
+
"phase5_monitoring": {
|
|
230
|
+
"name": "Phase 5: Monitoring & Iteration",
|
|
231
|
+
"description": "Ongoing monitoring and optimization",
|
|
232
|
+
"items": [
|
|
233
|
+
{
|
|
234
|
+
"id": "P5-01",
|
|
235
|
+
"task": "Google Search Console - Weekly check: queries, indexed pages, errors",
|
|
236
|
+
"status": "requires_deployment",
|
|
237
|
+
"notes": "Requires GSC setup first (P1-01)",
|
|
238
|
+
"implementedAt": null
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"id": "P5-02",
|
|
242
|
+
"task": "Track Rankings - Use free tier Ubersuggest/SERPRobot for 10-20 priority keywords",
|
|
243
|
+
"status": "pending",
|
|
244
|
+
"notes": "Set up after deployment and GSC verification",
|
|
245
|
+
"implementedAt": null
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"id": "P5-03",
|
|
249
|
+
"task": "Fix Crawl Errors - Check GSC Coverage and fix any errors",
|
|
250
|
+
"status": "requires_deployment",
|
|
251
|
+
"notes": "Requires GSC data",
|
|
252
|
+
"implementedAt": null
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"id": "P5-04",
|
|
256
|
+
"task": "Update Content - Refresh content every 3-6 months",
|
|
257
|
+
"status": "pending",
|
|
258
|
+
"notes": "Set reminder for quarterly content refresh",
|
|
259
|
+
"implementedAt": null
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
},
|
|
263
|
+
"aeo_aio_optimization": {
|
|
264
|
+
"name": "AEO & AIO Optimization",
|
|
265
|
+
"description": "Answer Engine Optimization and AI Optimization for ChatGPT, Claude, Perplexity visibility",
|
|
266
|
+
"items": [
|
|
267
|
+
{
|
|
268
|
+
"id": "AI-01",
|
|
269
|
+
"task": "FAQ Schema - Add FAQPage JSON-LD to main pages and blog posts",
|
|
270
|
+
"status": "completed",
|
|
271
|
+
"notes": "Expanded to 10 Q&A pairs in postbuild-seo.ts covering installation, CodePush comparison, rollback, staged rollouts, security, platform support.",
|
|
272
|
+
"implementedAt": "2026-04-10"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"id": "AI-02",
|
|
276
|
+
"task": "Answer-First Content - Start descriptions with direct, concise answers in first paragraph",
|
|
277
|
+
"status": "pending",
|
|
278
|
+
"notes": "Review all page content for answer-first structure",
|
|
279
|
+
"implementedAt": null
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"id": "AI-03",
|
|
283
|
+
"task": "How-to Guides - Step-by-step guides for common tasks",
|
|
284
|
+
"status": "pending",
|
|
285
|
+
"notes": "Docs have some guides. Need blog posts with 'How to' format.",
|
|
286
|
+
"implementedAt": null
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
"id": "AI-04",
|
|
290
|
+
"task": "Definition-Style Openings - Clear definitions at start of key pages",
|
|
291
|
+
"status": "pending",
|
|
292
|
+
"notes": "'Native Update is a Capacitor plugin that...' pattern on all key pages",
|
|
293
|
+
"implementedAt": null
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"id": "AI-05",
|
|
297
|
+
"task": "Comparison Content - 'Native Update vs X' style content",
|
|
298
|
+
"status": "pending",
|
|
299
|
+
"notes": "Same as P4-02, cross-referenced",
|
|
300
|
+
"implementedAt": null
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"id": "AI-06",
|
|
304
|
+
"task": "Structured Data Everywhere - Maximum schema markup coverage",
|
|
305
|
+
"status": "completed",
|
|
306
|
+
"notes": "WebSite, Organization, SoftwareApplication, FAQPage in postbuild. BreadcrumbList per-page via usePageSEO hook.",
|
|
307
|
+
"implementedAt": "2026-04-10"
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
"id": "AI-07",
|
|
311
|
+
"task": "Clear Product Description - 2-3 sentence quotable description for AI systems",
|
|
312
|
+
"status": "completed",
|
|
313
|
+
"notes": "Updated index.html hidden content with detailed, specific, quotable description including feature names and specifics.",
|
|
314
|
+
"implementedAt": "2026-04-10"
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"id": "AI-08",
|
|
318
|
+
"task": "Be Specific - Use exact numbers and specifics instead of vague claims",
|
|
319
|
+
"status": "completed",
|
|
320
|
+
"notes": "Updated descriptions to include '3 core features', specific feature names, framework list, installation commands.",
|
|
321
|
+
"implementedAt": "2026-04-10"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"id": "AI-09",
|
|
325
|
+
"task": "AI Crawler Access in robots.txt - Allow GPTBot, ClaudeBot, PerplexityBot etc.",
|
|
326
|
+
"status": "completed",
|
|
327
|
+
"notes": "Already implemented in robots.txt with full AI crawler allowlisting",
|
|
328
|
+
"implementedAt": "2026-03-27"
|
|
329
|
+
}
|
|
330
|
+
]
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
@@ -3,9 +3,23 @@ import Capacitor
|
|
|
3
3
|
import BackgroundTasks
|
|
4
4
|
import UserNotifications
|
|
5
5
|
|
|
6
|
+
/// BackgroundUpdatePlugin schedules silent OTA update checks via
|
|
7
|
+
/// `BGAppRefreshTask` on iOS 13+. The host app **must** declare the
|
|
8
|
+
/// scheduler identifier in its own `Info.plist` — the framework's plist
|
|
9
|
+
/// declaration does not propagate into the app bundle. Add:
|
|
10
|
+
///
|
|
11
|
+
/// <key>BGTaskSchedulerPermittedIdentifiers</key>
|
|
12
|
+
/// <array>
|
|
13
|
+
/// <string>com.aoneahsan.nativeupdate.background</string>
|
|
14
|
+
/// </array>
|
|
15
|
+
///
|
|
16
|
+
/// and (for the Capabilities pane) ensure `background-app-refresh` is
|
|
17
|
+
/// listed under `UIBackgroundModes`. Without those entries iOS will
|
|
18
|
+
/// silently refuse to register the task and background updates never
|
|
19
|
+
/// run — there is no runtime error.
|
|
6
20
|
@objc(BackgroundUpdatePlugin)
|
|
7
21
|
public class BackgroundUpdatePlugin: CAPPlugin {
|
|
8
|
-
|
|
22
|
+
|
|
9
23
|
private let backgroundTaskIdentifier = "com.aoneahsan.nativeupdate.background"
|
|
10
24
|
private var backgroundUpdateConfig: BackgroundUpdateConfig?
|
|
11
25
|
private var backgroundUpdateStatus = BackgroundUpdateStatus(
|
|
@@ -133,19 +147,49 @@ public class BackgroundUpdatePlugin: CAPPlugin {
|
|
|
133
147
|
|
|
134
148
|
private func scheduleBackgroundTask(interval: Int) {
|
|
135
149
|
guard #available(iOS 13.0, *) else {
|
|
136
|
-
NSLog("BackgroundTasks framework not available on iOS < 13.0")
|
|
150
|
+
NSLog("[native-update] BackgroundTasks framework not available on iOS < 13.0")
|
|
137
151
|
return
|
|
138
152
|
}
|
|
139
|
-
|
|
153
|
+
|
|
154
|
+
// Cancel any prior pending request with this identifier before
|
|
155
|
+
// submitting a new one. iOS documents submit() as replacing an
|
|
156
|
+
// existing request of the same identifier, but a few OS versions
|
|
157
|
+
// have been observed to fail the second submit with an
|
|
158
|
+
// already-scheduled error instead of replacing. Explicit cancel
|
|
159
|
+
// is the reliable path.
|
|
160
|
+
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: backgroundTaskIdentifier)
|
|
161
|
+
|
|
140
162
|
let request = BGAppRefreshTaskRequest(identifier: backgroundTaskIdentifier)
|
|
141
163
|
request.earliestBeginDate = Date(timeIntervalSinceNow: TimeInterval(interval / 1000))
|
|
142
|
-
|
|
164
|
+
|
|
143
165
|
do {
|
|
144
166
|
try BGTaskScheduler.shared.submit(request)
|
|
145
167
|
backgroundUpdateStatus.nextCheckTime = Int(Date().timeIntervalSince1970 * 1000) + interval
|
|
146
|
-
NSLog("Background task scheduled for \(interval)ms from now")
|
|
168
|
+
NSLog("[native-update] Background task scheduled for \(interval)ms from now")
|
|
169
|
+
} catch let error as BGTaskScheduler.Error {
|
|
170
|
+
// Surface a specific diagnostic. .notPermitted almost always
|
|
171
|
+
// means the host app's Info.plist is missing the scheduler
|
|
172
|
+
// identifier — which is a silent failure mode otherwise.
|
|
173
|
+
switch error.code {
|
|
174
|
+
case .notPermitted:
|
|
175
|
+
NSLog("[native-update] BGTaskScheduler .notPermitted — host app is missing BGTaskSchedulerPermittedIdentifiers entry for \(backgroundTaskIdentifier) in Info.plist")
|
|
176
|
+
case .tooManyPendingTaskRequests:
|
|
177
|
+
NSLog("[native-update] BGTaskScheduler .tooManyPendingTaskRequests — another task is already queued; background updates will run on the existing schedule")
|
|
178
|
+
case .unavailable:
|
|
179
|
+
NSLog("[native-update] BGTaskScheduler .unavailable — background tasks are disabled on this device (likely simulator or Low Power Mode)")
|
|
180
|
+
@unknown default:
|
|
181
|
+
NSLog("[native-update] Failed to schedule background task: \(error.localizedDescription)")
|
|
182
|
+
}
|
|
183
|
+
backgroundUpdateStatus.lastError = UpdateError(
|
|
184
|
+
code: "BGTASK_SUBMIT_FAILED",
|
|
185
|
+
message: error.localizedDescription
|
|
186
|
+
)
|
|
147
187
|
} catch {
|
|
148
|
-
NSLog("Failed to schedule background task: \(error.localizedDescription)")
|
|
188
|
+
NSLog("[native-update] Failed to schedule background task: \(error.localizedDescription)")
|
|
189
|
+
backgroundUpdateStatus.lastError = UpdateError(
|
|
190
|
+
code: "BGTASK_SUBMIT_FAILED",
|
|
191
|
+
message: error.localizedDescription
|
|
192
|
+
)
|
|
149
193
|
}
|
|
150
194
|
}
|
|
151
195
|
|