cordova-plugin-mserviceinterface-2.0 1.0.99 → 1.0.100
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/package.json +1 -1
- package/plugin.xml +5 -1
- package/scripts/mservice-deeplink-setup.js +1182 -0
- package/templates/ios/SceneDelegate.swift +258 -0
- package/www/mServiceAppLink.js +108 -0
|
@@ -0,0 +1,1182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var fs = require("fs");
|
|
4
|
+
var path = require("path");
|
|
5
|
+
|
|
6
|
+
function getPreferenceValue(configXml, preferenceName) {
|
|
7
|
+
var escapedName;
|
|
8
|
+
var pattern;
|
|
9
|
+
var match;
|
|
10
|
+
|
|
11
|
+
escapedName = preferenceName.replace(
|
|
12
|
+
/[.*+?^${}()|[\]\\]/g,
|
|
13
|
+
"\\$&"
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
pattern = new RegExp(
|
|
17
|
+
"<preference\\s+" +
|
|
18
|
+
"(?=[^>]*\\bname\\s*=\\s*[\"']" + escapedName + "[\"'])" +
|
|
19
|
+
"(?=[^>]*\\bvalue\\s*=\\s*[\"']([^\"']*)[\"'])" +
|
|
20
|
+
"[^>]*/?>",
|
|
21
|
+
"i"
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
match = configXml.match(pattern);
|
|
25
|
+
|
|
26
|
+
return match !== null ? match[1].trim() : "";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function normalizePath(deepLinkPath) {
|
|
30
|
+
if (deepLinkPath === "") {
|
|
31
|
+
return "/";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (deepLinkPath.charAt(0) !== "/") {
|
|
35
|
+
return "/" + deepLinkPath;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return deepLinkPath;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function validateConfiguration(configuration) {
|
|
42
|
+
var errors = [];
|
|
43
|
+
|
|
44
|
+
if (configuration.scheme === "") {
|
|
45
|
+
errors.push(
|
|
46
|
+
"MServiceDeepLinkScheme is missing in config.xml"
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (configuration.host === "") {
|
|
51
|
+
errors.push(
|
|
52
|
+
"MServiceDeepLinkHost is missing in config.xml"
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (configuration.path === "") {
|
|
57
|
+
errors.push(
|
|
58
|
+
"MServiceDeepLinkPath is missing in config.xml"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (
|
|
63
|
+
configuration.scheme !== "" &&
|
|
64
|
+
configuration.scheme !== "https"
|
|
65
|
+
) {
|
|
66
|
+
errors.push(
|
|
67
|
+
"MServiceDeepLinkScheme must be https for verified App Links and Universal Links"
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (
|
|
72
|
+
configuration.host.indexOf("http://") === 0 ||
|
|
73
|
+
configuration.host.indexOf("https://") === 0
|
|
74
|
+
) {
|
|
75
|
+
errors.push(
|
|
76
|
+
"MServiceDeepLinkHost must contain only the hostname, without https://"
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (
|
|
81
|
+
configuration.iosAssociatedDomain !== "" &&
|
|
82
|
+
configuration.iosAssociatedDomain.indexOf("applinks:") !== 0
|
|
83
|
+
) {
|
|
84
|
+
errors.push(
|
|
85
|
+
"MServiceIOSAssociatedDomain must start with applinks:"
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (errors.length !== 0) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
"Invalid deep-link configuration:\n- " +
|
|
92
|
+
errors.join("\n- ")
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function escapeRegExp(value) {
|
|
97
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function escapeXmlAttribute(value) {
|
|
101
|
+
return String(value)
|
|
102
|
+
.replace(/&/g, "&")
|
|
103
|
+
.replace(/"/g, """)
|
|
104
|
+
.replace(/</g, "<")
|
|
105
|
+
.replace(/>/g, ">");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function getAndroidManifestPath(projectRoot) {
|
|
109
|
+
var possiblePaths = [
|
|
110
|
+
path.join(
|
|
111
|
+
projectRoot,
|
|
112
|
+
"platforms",
|
|
113
|
+
"android",
|
|
114
|
+
"app",
|
|
115
|
+
"src",
|
|
116
|
+
"main",
|
|
117
|
+
"AndroidManifest.xml"
|
|
118
|
+
),
|
|
119
|
+
path.join(
|
|
120
|
+
projectRoot,
|
|
121
|
+
"platforms",
|
|
122
|
+
"android",
|
|
123
|
+
"AndroidManifest.xml"
|
|
124
|
+
)
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
var index;
|
|
128
|
+
|
|
129
|
+
for (index = 0; index < possiblePaths.length; index += 1) {
|
|
130
|
+
if (fs.existsSync(possiblePaths[index])) {
|
|
131
|
+
return possiblePaths[index];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return "";
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function setActivityAttribute(openingTag, attributeName, attributeValue) {
|
|
139
|
+
var attributePattern;
|
|
140
|
+
|
|
141
|
+
attributePattern = new RegExp(
|
|
142
|
+
"\\s+" +
|
|
143
|
+
escapeRegExp(attributeName) +
|
|
144
|
+
"\\s*=\\s*[\"'][^\"']*[\"']",
|
|
145
|
+
"i"
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
if (attributePattern.test(openingTag)) {
|
|
149
|
+
return openingTag.replace(
|
|
150
|
+
attributePattern,
|
|
151
|
+
" " +
|
|
152
|
+
attributeName +
|
|
153
|
+
"=\"" +
|
|
154
|
+
escapeXmlAttribute(attributeValue) +
|
|
155
|
+
"\""
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return openingTag.replace(
|
|
160
|
+
/>$/,
|
|
161
|
+
" " +
|
|
162
|
+
attributeName +
|
|
163
|
+
"=\"" +
|
|
164
|
+
escapeXmlAttribute(attributeValue) +
|
|
165
|
+
"\">"
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function configureAndroidAppLink(projectRoot, configuration) {
|
|
170
|
+
var manifestPath;
|
|
171
|
+
var manifestContent;
|
|
172
|
+
var activityPattern;
|
|
173
|
+
var activityMatch;
|
|
174
|
+
var activityBlock;
|
|
175
|
+
var updatedActivityBlock;
|
|
176
|
+
var markerPattern;
|
|
177
|
+
var intentFilter;
|
|
178
|
+
|
|
179
|
+
manifestPath = getAndroidManifestPath(projectRoot);
|
|
180
|
+
|
|
181
|
+
if (manifestPath === "") {
|
|
182
|
+
throw new Error(
|
|
183
|
+
"AndroidManifest.xml could not be found under platforms/android."
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
manifestContent = fs.readFileSync(manifestPath, "utf8");
|
|
188
|
+
|
|
189
|
+
activityPattern =
|
|
190
|
+
/<activity\b[^>]*android:name\s*=\s*["'][^"']*MainActivity["'][^>]*>[\s\S]*?<\/activity>/i;
|
|
191
|
+
|
|
192
|
+
activityMatch = manifestContent.match(activityPattern);
|
|
193
|
+
|
|
194
|
+
if (activityMatch === null) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
"MainActivity declaration could not be found in AndroidManifest.xml."
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
activityBlock = activityMatch[0];
|
|
201
|
+
|
|
202
|
+
/*
|
|
203
|
+
* Ensure the activity receives App Links when the app is already open.
|
|
204
|
+
*/
|
|
205
|
+
updatedActivityBlock = activityBlock.replace(
|
|
206
|
+
/^<activity\b[^>]*>/i,
|
|
207
|
+
function (openingTag) {
|
|
208
|
+
var updatedOpeningTag;
|
|
209
|
+
|
|
210
|
+
updatedOpeningTag = setActivityAttribute(
|
|
211
|
+
openingTag,
|
|
212
|
+
"android:exported",
|
|
213
|
+
"true"
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
updatedOpeningTag = setActivityAttribute(
|
|
217
|
+
updatedOpeningTag,
|
|
218
|
+
"android:launchMode",
|
|
219
|
+
"singleTask"
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
return updatedOpeningTag;
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
intentFilter =
|
|
227
|
+
"\n <!-- MService App Link - START -->\n" +
|
|
228
|
+
" <intent-filter android:autoVerify=\"true\">\n" +
|
|
229
|
+
" <action android:name=\"android.intent.action.VIEW\" />\n" +
|
|
230
|
+
" <category android:name=\"android.intent.category.DEFAULT\" />\n" +
|
|
231
|
+
" <category android:name=\"android.intent.category.BROWSABLE\" />\n" +
|
|
232
|
+
" <data\n" +
|
|
233
|
+
" android:scheme=\"" +
|
|
234
|
+
escapeXmlAttribute(configuration.scheme) +
|
|
235
|
+
"\"\n" +
|
|
236
|
+
" android:host=\"" +
|
|
237
|
+
escapeXmlAttribute(configuration.host) +
|
|
238
|
+
"\"\n" +
|
|
239
|
+
" android:path=\"" +
|
|
240
|
+
escapeXmlAttribute(configuration.path) +
|
|
241
|
+
"\" />\n" +
|
|
242
|
+
" </intent-filter>\n" +
|
|
243
|
+
" <!-- MService App Link - END -->\n";
|
|
244
|
+
|
|
245
|
+
markerPattern =
|
|
246
|
+
/\s*<!-- MService App Link - START -->[\s\S]*?<!-- MService App Link - END -->\s*/i;
|
|
247
|
+
|
|
248
|
+
/*
|
|
249
|
+
* Replace an existing hook-generated filter when configuration changes.
|
|
250
|
+
*/
|
|
251
|
+
if (markerPattern.test(updatedActivityBlock)) {
|
|
252
|
+
updatedActivityBlock = updatedActivityBlock.replace(
|
|
253
|
+
markerPattern,
|
|
254
|
+
intentFilter
|
|
255
|
+
);
|
|
256
|
+
} else {
|
|
257
|
+
updatedActivityBlock = updatedActivityBlock.replace(
|
|
258
|
+
/<\/activity>\s*$/i,
|
|
259
|
+
intentFilter + " </activity>"
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
manifestContent = manifestContent.replace(
|
|
264
|
+
activityPattern,
|
|
265
|
+
updatedActivityBlock
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
fs.writeFileSync(
|
|
269
|
+
manifestPath,
|
|
270
|
+
manifestContent,
|
|
271
|
+
"utf8"
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
console.log(
|
|
275
|
+
"[MService Deep Link] Android App Link configured: " +
|
|
276
|
+
configuration.scheme +
|
|
277
|
+
"://" +
|
|
278
|
+
configuration.host +
|
|
279
|
+
configuration.path
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
console.log(
|
|
283
|
+
"[MService Deep Link] Android manifest updated: " +
|
|
284
|
+
manifestPath
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function findFileRecursively(directoryPath, fileName) {
|
|
289
|
+
var entries;
|
|
290
|
+
var index;
|
|
291
|
+
var entryPath;
|
|
292
|
+
var status;
|
|
293
|
+
var result;
|
|
294
|
+
|
|
295
|
+
if (!fs.existsSync(directoryPath)) {
|
|
296
|
+
return "";
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
entries = fs.readdirSync(directoryPath);
|
|
300
|
+
|
|
301
|
+
for (index = 0; index < entries.length; index += 1) {
|
|
302
|
+
entryPath = path.join(directoryPath, entries[index]);
|
|
303
|
+
status = fs.statSync(entryPath);
|
|
304
|
+
|
|
305
|
+
if (status.isFile() && entries[index] === fileName) {
|
|
306
|
+
return entryPath;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (status.isDirectory()) {
|
|
310
|
+
result = findFileRecursively(entryPath, fileName);
|
|
311
|
+
|
|
312
|
+
if (result !== "") {
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return "";
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function ensureJavaImport(
|
|
322
|
+
javaContent,
|
|
323
|
+
importStatement,
|
|
324
|
+
newLine
|
|
325
|
+
) {
|
|
326
|
+
var importPattern;
|
|
327
|
+
var importMatch;
|
|
328
|
+
var lastImportMatch;
|
|
329
|
+
var packageMatch;
|
|
330
|
+
var insertionIndex;
|
|
331
|
+
|
|
332
|
+
if (javaContent.indexOf(importStatement) !== -1) {
|
|
333
|
+
return javaContent;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
importPattern = /^import[^\r\n]+;$/gm;
|
|
337
|
+
lastImportMatch = null;
|
|
338
|
+
|
|
339
|
+
while (
|
|
340
|
+
(importMatch = importPattern.exec(javaContent)) !== null
|
|
341
|
+
) {
|
|
342
|
+
lastImportMatch = importMatch;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (lastImportMatch !== null) {
|
|
346
|
+
insertionIndex =
|
|
347
|
+
lastImportMatch.index +
|
|
348
|
+
lastImportMatch[0].length;
|
|
349
|
+
|
|
350
|
+
return (
|
|
351
|
+
javaContent.substring(0, insertionIndex) +
|
|
352
|
+
newLine +
|
|
353
|
+
importStatement +
|
|
354
|
+
javaContent.substring(insertionIndex)
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
packageMatch =
|
|
359
|
+
/^package[^\r\n]+;$/m.exec(javaContent);
|
|
360
|
+
|
|
361
|
+
if (packageMatch === null) {
|
|
362
|
+
throw new Error(
|
|
363
|
+
"Package declaration was not found in MainActivity.java."
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
insertionIndex =
|
|
368
|
+
packageMatch.index +
|
|
369
|
+
packageMatch[0].length;
|
|
370
|
+
|
|
371
|
+
return (
|
|
372
|
+
javaContent.substring(0, insertionIndex) +
|
|
373
|
+
newLine +
|
|
374
|
+
newLine +
|
|
375
|
+
importStatement +
|
|
376
|
+
javaContent.substring(insertionIndex)
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function insertBeforeFinalClassBrace(
|
|
381
|
+
javaContent,
|
|
382
|
+
javaBlock,
|
|
383
|
+
newLine
|
|
384
|
+
) {
|
|
385
|
+
var finalBraceIndex;
|
|
386
|
+
|
|
387
|
+
finalBraceIndex = javaContent.lastIndexOf("}");
|
|
388
|
+
|
|
389
|
+
if (finalBraceIndex === -1) {
|
|
390
|
+
throw new Error(
|
|
391
|
+
"Final class closing brace was not found in MainActivity.java."
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return (
|
|
396
|
+
javaContent.substring(0, finalBraceIndex) +
|
|
397
|
+
javaBlock +
|
|
398
|
+
newLine +
|
|
399
|
+
javaContent.substring(finalBraceIndex)
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function configureAndroidMainActivity(projectRoot) {
|
|
404
|
+
var javaRoot;
|
|
405
|
+
var mainActivityPath;
|
|
406
|
+
var javaContent;
|
|
407
|
+
var originalContent;
|
|
408
|
+
var newLine;
|
|
409
|
+
var onCreateCall;
|
|
410
|
+
var onNewIntentBlock;
|
|
411
|
+
var helperMethodsBlock;
|
|
412
|
+
var loadUrlPattern;
|
|
413
|
+
var existingOnNewIntentPattern;
|
|
414
|
+
var updatedExistingMethod;
|
|
415
|
+
|
|
416
|
+
javaRoot = path.join(
|
|
417
|
+
projectRoot,
|
|
418
|
+
"platforms",
|
|
419
|
+
"android",
|
|
420
|
+
"app",
|
|
421
|
+
"src",
|
|
422
|
+
"main",
|
|
423
|
+
"java"
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
mainActivityPath = findFileRecursively(
|
|
427
|
+
javaRoot,
|
|
428
|
+
"MainActivity.java"
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
if (mainActivityPath === "") {
|
|
432
|
+
throw new Error(
|
|
433
|
+
"MainActivity.java could not be found under: " +
|
|
434
|
+
javaRoot
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
javaContent = fs.readFileSync(
|
|
439
|
+
mainActivityPath,
|
|
440
|
+
"utf8"
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
originalContent = javaContent;
|
|
444
|
+
|
|
445
|
+
newLine =
|
|
446
|
+
javaContent.indexOf("\r\n") !== -1
|
|
447
|
+
? "\r\n"
|
|
448
|
+
: "\n";
|
|
449
|
+
|
|
450
|
+
/*
|
|
451
|
+
* Ensure required imports.
|
|
452
|
+
*/
|
|
453
|
+
javaContent = ensureJavaImport(
|
|
454
|
+
javaContent,
|
|
455
|
+
"import android.content.Intent;",
|
|
456
|
+
newLine
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
javaContent = ensureJavaImport(
|
|
460
|
+
javaContent,
|
|
461
|
+
"import android.net.Uri;",
|
|
462
|
+
newLine
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
javaContent = ensureJavaImport(
|
|
466
|
+
javaContent,
|
|
467
|
+
"import org.json.JSONObject;",
|
|
468
|
+
newLine
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
/*
|
|
472
|
+
* Cold-start handling:
|
|
473
|
+
* App closed -> App Link opens the app.
|
|
474
|
+
*/
|
|
475
|
+
if (
|
|
476
|
+
!/handleAppLinkIntent\s*\(\s*getIntent\s*\(\s*\)\s*\)\s*;/.test(
|
|
477
|
+
javaContent
|
|
478
|
+
)
|
|
479
|
+
) {
|
|
480
|
+
onCreateCall =
|
|
481
|
+
newLine +
|
|
482
|
+
newLine +
|
|
483
|
+
" // MService App Link onCreate - START" +
|
|
484
|
+
newLine +
|
|
485
|
+
" handleAppLinkIntent(getIntent());" +
|
|
486
|
+
newLine +
|
|
487
|
+
" // MService App Link onCreate - END";
|
|
488
|
+
|
|
489
|
+
loadUrlPattern =
|
|
490
|
+
/loadUrl\s*\(\s*launchUrl\s*\)\s*;/;
|
|
491
|
+
|
|
492
|
+
if (!loadUrlPattern.test(javaContent)) {
|
|
493
|
+
throw new Error(
|
|
494
|
+
"loadUrl(launchUrl) was not found in MainActivity.java."
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
javaContent = javaContent.replace(
|
|
499
|
+
loadUrlPattern,
|
|
500
|
+
function (loadUrlStatement) {
|
|
501
|
+
return loadUrlStatement + onCreateCall;
|
|
502
|
+
}
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/*
|
|
507
|
+
* Background/running handling:
|
|
508
|
+
* App already open -> App Link arrives through onNewIntent.
|
|
509
|
+
*/
|
|
510
|
+
if (
|
|
511
|
+
javaContent.indexOf(
|
|
512
|
+
"protected void onNewIntent(Intent intent)"
|
|
513
|
+
) === -1
|
|
514
|
+
) {
|
|
515
|
+
onNewIntentBlock =
|
|
516
|
+
newLine +
|
|
517
|
+
" // MService App Link onNewIntent - START" +
|
|
518
|
+
newLine +
|
|
519
|
+
" @Override" +
|
|
520
|
+
newLine +
|
|
521
|
+
" protected void onNewIntent(Intent intent) {" +
|
|
522
|
+
newLine +
|
|
523
|
+
" super.onNewIntent(intent);" +
|
|
524
|
+
newLine +
|
|
525
|
+
" setIntent(intent);" +
|
|
526
|
+
newLine +
|
|
527
|
+
newLine +
|
|
528
|
+
" handleAppLinkIntent(intent);" +
|
|
529
|
+
newLine +
|
|
530
|
+
" }" +
|
|
531
|
+
newLine +
|
|
532
|
+
" // MService App Link onNewIntent - END" +
|
|
533
|
+
newLine;
|
|
534
|
+
|
|
535
|
+
javaContent = insertBeforeFinalClassBrace(
|
|
536
|
+
javaContent,
|
|
537
|
+
onNewIntentBlock,
|
|
538
|
+
newLine
|
|
539
|
+
);
|
|
540
|
+
} else if (
|
|
541
|
+
javaContent.indexOf(
|
|
542
|
+
"handleAppLinkIntent(intent);"
|
|
543
|
+
) === -1
|
|
544
|
+
) {
|
|
545
|
+
existingOnNewIntentPattern =
|
|
546
|
+
/(protected\s+void\s+onNewIntent\s*\(\s*Intent\s+intent\s*\)\s*\{[\s\S]*?setIntent\s*\(\s*intent\s*\)\s*;)/;
|
|
547
|
+
|
|
548
|
+
if (existingOnNewIntentPattern.test(javaContent)) {
|
|
549
|
+
javaContent = javaContent.replace(
|
|
550
|
+
existingOnNewIntentPattern,
|
|
551
|
+
function (methodStart) {
|
|
552
|
+
return (
|
|
553
|
+
methodStart +
|
|
554
|
+
newLine +
|
|
555
|
+
newLine +
|
|
556
|
+
" handleAppLinkIntent(intent);"
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
);
|
|
560
|
+
} else {
|
|
561
|
+
updatedExistingMethod = javaContent.replace(
|
|
562
|
+
/(protected\s+void\s+onNewIntent\s*\(\s*Intent\s+intent\s*\)\s*\{[\s\S]*?super\.onNewIntent\s*\(\s*intent\s*\)\s*;)/,
|
|
563
|
+
function (methodStart) {
|
|
564
|
+
return (
|
|
565
|
+
methodStart +
|
|
566
|
+
newLine +
|
|
567
|
+
" setIntent(intent);" +
|
|
568
|
+
newLine +
|
|
569
|
+
newLine +
|
|
570
|
+
" handleAppLinkIntent(intent);"
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
);
|
|
574
|
+
|
|
575
|
+
if (updatedExistingMethod === javaContent) {
|
|
576
|
+
throw new Error(
|
|
577
|
+
"Existing onNewIntent method could not be updated safely."
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
javaContent = updatedExistingMethod;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/*
|
|
586
|
+
* Add the common native-to-JavaScript bridge.
|
|
587
|
+
*/
|
|
588
|
+
if (
|
|
589
|
+
javaContent.indexOf(
|
|
590
|
+
"private void handleAppLinkIntent(Intent intent)"
|
|
591
|
+
) === -1
|
|
592
|
+
) {
|
|
593
|
+
helperMethodsBlock =
|
|
594
|
+
newLine +
|
|
595
|
+
" // MService App Link Methods - START" +
|
|
596
|
+
newLine +
|
|
597
|
+
" private void handleAppLinkIntent(Intent intent) {" +
|
|
598
|
+
newLine +
|
|
599
|
+
" if (intent == null) {" +
|
|
600
|
+
newLine +
|
|
601
|
+
" return;" +
|
|
602
|
+
newLine +
|
|
603
|
+
" }" +
|
|
604
|
+
newLine +
|
|
605
|
+
newLine +
|
|
606
|
+
" if (!Intent.ACTION_VIEW.equals(intent.getAction())) {" +
|
|
607
|
+
newLine +
|
|
608
|
+
" return;" +
|
|
609
|
+
newLine +
|
|
610
|
+
" }" +
|
|
611
|
+
newLine +
|
|
612
|
+
newLine +
|
|
613
|
+
" Uri data = intent.getData();" +
|
|
614
|
+
newLine +
|
|
615
|
+
newLine +
|
|
616
|
+
" if (data == null) {" +
|
|
617
|
+
newLine +
|
|
618
|
+
" return;" +
|
|
619
|
+
newLine +
|
|
620
|
+
" }" +
|
|
621
|
+
newLine +
|
|
622
|
+
newLine +
|
|
623
|
+
" sendAppLinkToJavaScript(data.toString(), 0);" +
|
|
624
|
+
newLine +
|
|
625
|
+
" }" +
|
|
626
|
+
newLine +
|
|
627
|
+
newLine +
|
|
628
|
+
" private void sendAppLinkToJavaScript(" +
|
|
629
|
+
newLine +
|
|
630
|
+
" final String appLinkUrl," +
|
|
631
|
+
newLine +
|
|
632
|
+
" final int retryCount) {" +
|
|
633
|
+
newLine +
|
|
634
|
+
newLine +
|
|
635
|
+
" if (" +
|
|
636
|
+
newLine +
|
|
637
|
+
" appView == null ||" +
|
|
638
|
+
newLine +
|
|
639
|
+
" appView.getView() == null ||" +
|
|
640
|
+
newLine +
|
|
641
|
+
" appView.getEngine() == null) {" +
|
|
642
|
+
newLine +
|
|
643
|
+
newLine +
|
|
644
|
+
" if (retryCount < 30) {" +
|
|
645
|
+
newLine +
|
|
646
|
+
" getWindow().getDecorView().postDelayed(" +
|
|
647
|
+
newLine +
|
|
648
|
+
" new Runnable() {" +
|
|
649
|
+
newLine +
|
|
650
|
+
" @Override" +
|
|
651
|
+
newLine +
|
|
652
|
+
" public void run() {" +
|
|
653
|
+
newLine +
|
|
654
|
+
" sendAppLinkToJavaScript(" +
|
|
655
|
+
newLine +
|
|
656
|
+
" appLinkUrl," +
|
|
657
|
+
newLine +
|
|
658
|
+
" retryCount + 1" +
|
|
659
|
+
newLine +
|
|
660
|
+
" );" +
|
|
661
|
+
newLine +
|
|
662
|
+
" }" +
|
|
663
|
+
newLine +
|
|
664
|
+
" }," +
|
|
665
|
+
newLine +
|
|
666
|
+
" 300" +
|
|
667
|
+
newLine +
|
|
668
|
+
" );" +
|
|
669
|
+
newLine +
|
|
670
|
+
" }" +
|
|
671
|
+
newLine +
|
|
672
|
+
newLine +
|
|
673
|
+
" return;" +
|
|
674
|
+
newLine +
|
|
675
|
+
" }" +
|
|
676
|
+
newLine +
|
|
677
|
+
newLine +
|
|
678
|
+
" appView.getView().postDelayed(" +
|
|
679
|
+
newLine +
|
|
680
|
+
" new Runnable() {" +
|
|
681
|
+
newLine +
|
|
682
|
+
" @Override" +
|
|
683
|
+
newLine +
|
|
684
|
+
" public void run() {" +
|
|
685
|
+
newLine +
|
|
686
|
+
" String quotedUrl =" +
|
|
687
|
+
newLine +
|
|
688
|
+
" JSONObject.quote(appLinkUrl);" +
|
|
689
|
+
newLine +
|
|
690
|
+
newLine +
|
|
691
|
+
" String js =" +
|
|
692
|
+
newLine +
|
|
693
|
+
" \"window.mServicePendingUniversalLink = \" +" +
|
|
694
|
+
newLine +
|
|
695
|
+
" quotedUrl +" +
|
|
696
|
+
newLine +
|
|
697
|
+
" \";\" +" +
|
|
698
|
+
newLine +
|
|
699
|
+
" \"try {\"" +
|
|
700
|
+
newLine +
|
|
701
|
+
" + \"window.localStorage.setItem(\"" +
|
|
702
|
+
newLine +
|
|
703
|
+
" + \"'mServicePendingUniversalLink', \"" +
|
|
704
|
+
newLine +
|
|
705
|
+
" + quotedUrl" +
|
|
706
|
+
newLine +
|
|
707
|
+
" + \");\"" +
|
|
708
|
+
newLine +
|
|
709
|
+
" + \"} catch(e) {}\"" +
|
|
710
|
+
newLine +
|
|
711
|
+
" + \"if (window.handleOpenURL) {\"" +
|
|
712
|
+
newLine +
|
|
713
|
+
" + \"window.handleOpenURL(\"" +
|
|
714
|
+
newLine +
|
|
715
|
+
" + quotedUrl" +
|
|
716
|
+
newLine +
|
|
717
|
+
" + \");\"" +
|
|
718
|
+
newLine +
|
|
719
|
+
" + \"window.mServicePendingUniversalLink = '';\"" +
|
|
720
|
+
newLine +
|
|
721
|
+
" + \"try {\"" +
|
|
722
|
+
newLine +
|
|
723
|
+
" + \"window.localStorage.removeItem(\"" +
|
|
724
|
+
newLine +
|
|
725
|
+
" + \"'mServicePendingUniversalLink'\"" +
|
|
726
|
+
newLine +
|
|
727
|
+
" + \");\"" +
|
|
728
|
+
newLine +
|
|
729
|
+
" + \"} catch(e) {}\"" +
|
|
730
|
+
newLine +
|
|
731
|
+
" + \"}\";" +
|
|
732
|
+
newLine +
|
|
733
|
+
newLine +
|
|
734
|
+
" appView.getEngine()" +
|
|
735
|
+
newLine +
|
|
736
|
+
" .evaluateJavascript(js, null);" +
|
|
737
|
+
newLine +
|
|
738
|
+
" }" +
|
|
739
|
+
newLine +
|
|
740
|
+
" }," +
|
|
741
|
+
newLine +
|
|
742
|
+
" 300" +
|
|
743
|
+
newLine +
|
|
744
|
+
" );" +
|
|
745
|
+
newLine +
|
|
746
|
+
" }" +
|
|
747
|
+
newLine +
|
|
748
|
+
" // MService App Link Methods - END" +
|
|
749
|
+
newLine;
|
|
750
|
+
|
|
751
|
+
javaContent = insertBeforeFinalClassBrace(
|
|
752
|
+
javaContent,
|
|
753
|
+
helperMethodsBlock,
|
|
754
|
+
newLine
|
|
755
|
+
);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
if (javaContent !== originalContent) {
|
|
759
|
+
fs.writeFileSync(
|
|
760
|
+
mainActivityPath,
|
|
761
|
+
javaContent,
|
|
762
|
+
"utf8"
|
|
763
|
+
);
|
|
764
|
+
|
|
765
|
+
console.log(
|
|
766
|
+
"[MService Deep Link] MainActivity.java configured: " +
|
|
767
|
+
mainActivityPath
|
|
768
|
+
);
|
|
769
|
+
} else {
|
|
770
|
+
console.log(
|
|
771
|
+
"[MService Deep Link] MainActivity.java already configured."
|
|
772
|
+
);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
function escapeXmlText(value) {
|
|
776
|
+
return String(value)
|
|
777
|
+
.replace(/&/g, "&")
|
|
778
|
+
.replace(/</g, "<")
|
|
779
|
+
.replace(/>/g, ">");
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
function getIOSEntitlementPaths(projectRoot) {
|
|
783
|
+
var iosRoot;
|
|
784
|
+
var debugEntitlementPath;
|
|
785
|
+
var releaseEntitlementPath;
|
|
786
|
+
|
|
787
|
+
iosRoot = path.join(
|
|
788
|
+
projectRoot,
|
|
789
|
+
"platforms",
|
|
790
|
+
"ios"
|
|
791
|
+
);
|
|
792
|
+
|
|
793
|
+
if (!fs.existsSync(iosRoot)) {
|
|
794
|
+
throw new Error(
|
|
795
|
+
"The iOS platform directory was not found: " +
|
|
796
|
+
iosRoot
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/*
|
|
801
|
+
* findFileRecursively was added during the Android
|
|
802
|
+
* MainActivity automation step.
|
|
803
|
+
*/
|
|
804
|
+
debugEntitlementPath = findFileRecursively(
|
|
805
|
+
iosRoot,
|
|
806
|
+
"Entitlements-Debug.plist"
|
|
807
|
+
);
|
|
808
|
+
|
|
809
|
+
releaseEntitlementPath = findFileRecursively(
|
|
810
|
+
iosRoot,
|
|
811
|
+
"Entitlements-Release.plist"
|
|
812
|
+
);
|
|
813
|
+
|
|
814
|
+
if (debugEntitlementPath === "") {
|
|
815
|
+
throw new Error(
|
|
816
|
+
"Entitlements-Debug.plist was not found under " +
|
|
817
|
+
iosRoot
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
if (releaseEntitlementPath === "") {
|
|
822
|
+
throw new Error(
|
|
823
|
+
"Entitlements-Release.plist was not found under " +
|
|
824
|
+
iosRoot
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
return [
|
|
829
|
+
debugEntitlementPath,
|
|
830
|
+
releaseEntitlementPath
|
|
831
|
+
];
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
function updateAssociatedDomainsEntitlement(
|
|
835
|
+
entitlementPath,
|
|
836
|
+
associatedDomain
|
|
837
|
+
) {
|
|
838
|
+
var plistContent;
|
|
839
|
+
var originalContent;
|
|
840
|
+
var newLine;
|
|
841
|
+
var entitlementBlock;
|
|
842
|
+
var entitlementPattern;
|
|
843
|
+
var closingDictIndex;
|
|
844
|
+
|
|
845
|
+
plistContent = fs.readFileSync(
|
|
846
|
+
entitlementPath,
|
|
847
|
+
"utf8"
|
|
848
|
+
);
|
|
849
|
+
|
|
850
|
+
originalContent = plistContent;
|
|
851
|
+
|
|
852
|
+
newLine =
|
|
853
|
+
plistContent.indexOf("\r\n") !== -1
|
|
854
|
+
? "\r\n"
|
|
855
|
+
: "\n";
|
|
856
|
+
|
|
857
|
+
if (
|
|
858
|
+
plistContent.indexOf("<plist") === -1 ||
|
|
859
|
+
plistContent.indexOf("<dict>") === -1
|
|
860
|
+
) {
|
|
861
|
+
throw new Error(
|
|
862
|
+
"Invalid entitlement plist format: " +
|
|
863
|
+
entitlementPath
|
|
864
|
+
);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
entitlementBlock =
|
|
868
|
+
" <key>" +
|
|
869
|
+
"com.apple.developer.associated-domains" +
|
|
870
|
+
"</key>" +
|
|
871
|
+
newLine +
|
|
872
|
+
" <array>" +
|
|
873
|
+
newLine +
|
|
874
|
+
" <string>" +
|
|
875
|
+
escapeXmlText(associatedDomain) +
|
|
876
|
+
"</string>" +
|
|
877
|
+
newLine +
|
|
878
|
+
" </array>";
|
|
879
|
+
|
|
880
|
+
/*
|
|
881
|
+
* Replace an existing Associated Domains entitlement.
|
|
882
|
+
* This prevents duplicates when cordova prepare runs again.
|
|
883
|
+
*/
|
|
884
|
+
entitlementPattern =
|
|
885
|
+
/[ \t]*<key>\s*com\.apple\.developer\.associated-domains\s*<\/key>\s*<array>[\s\S]*?<\/array>/i;
|
|
886
|
+
|
|
887
|
+
if (entitlementPattern.test(plistContent)) {
|
|
888
|
+
plistContent = plistContent.replace(
|
|
889
|
+
entitlementPattern,
|
|
890
|
+
entitlementBlock
|
|
891
|
+
);
|
|
892
|
+
} else {
|
|
893
|
+
closingDictIndex = plistContent.lastIndexOf(
|
|
894
|
+
"</dict>"
|
|
895
|
+
);
|
|
896
|
+
|
|
897
|
+
if (closingDictIndex === -1) {
|
|
898
|
+
throw new Error(
|
|
899
|
+
"The closing </dict> was not found in: " +
|
|
900
|
+
entitlementPath
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
plistContent =
|
|
905
|
+
plistContent.substring(
|
|
906
|
+
0,
|
|
907
|
+
closingDictIndex
|
|
908
|
+
) +
|
|
909
|
+
entitlementBlock +
|
|
910
|
+
newLine +
|
|
911
|
+
plistContent.substring(
|
|
912
|
+
closingDictIndex
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
if (plistContent !== originalContent) {
|
|
917
|
+
fs.writeFileSync(
|
|
918
|
+
entitlementPath,
|
|
919
|
+
plistContent,
|
|
920
|
+
"utf8"
|
|
921
|
+
);
|
|
922
|
+
|
|
923
|
+
console.log(
|
|
924
|
+
"[MService Deep Link] iOS entitlement updated: " +
|
|
925
|
+
entitlementPath
|
|
926
|
+
);
|
|
927
|
+
} else {
|
|
928
|
+
console.log(
|
|
929
|
+
"[MService Deep Link] iOS entitlement already configured: " +
|
|
930
|
+
entitlementPath
|
|
931
|
+
);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
function configureIOSAssociatedDomains(
|
|
936
|
+
projectRoot,
|
|
937
|
+
configuration
|
|
938
|
+
) {
|
|
939
|
+
var entitlementPaths;
|
|
940
|
+
var index;
|
|
941
|
+
|
|
942
|
+
if (
|
|
943
|
+
configuration.iosAssociatedDomain === undefined ||
|
|
944
|
+
configuration.iosAssociatedDomain === ""
|
|
945
|
+
) {
|
|
946
|
+
throw new Error(
|
|
947
|
+
"MServiceIOSAssociatedDomain is required " +
|
|
948
|
+
"when preparing the iOS platform."
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
if (
|
|
953
|
+
configuration.iosAssociatedDomain.indexOf(
|
|
954
|
+
"applinks:"
|
|
955
|
+
) !== 0
|
|
956
|
+
) {
|
|
957
|
+
throw new Error(
|
|
958
|
+
"MServiceIOSAssociatedDomain must start " +
|
|
959
|
+
"with applinks:."
|
|
960
|
+
);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
entitlementPaths = getIOSEntitlementPaths(
|
|
964
|
+
projectRoot
|
|
965
|
+
);
|
|
966
|
+
|
|
967
|
+
for (
|
|
968
|
+
index = 0;
|
|
969
|
+
index < entitlementPaths.length;
|
|
970
|
+
index += 1
|
|
971
|
+
) {
|
|
972
|
+
updateAssociatedDomainsEntitlement(
|
|
973
|
+
entitlementPaths[index],
|
|
974
|
+
configuration.iosAssociatedDomain
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
console.log(
|
|
979
|
+
"[MService Deep Link] iOS Associated Domain configured: " +
|
|
980
|
+
configuration.iosAssociatedDomain
|
|
981
|
+
);
|
|
982
|
+
}
|
|
983
|
+
function configureIOSSceneDelegate(projectRoot) {
|
|
984
|
+
var pluginRoot;
|
|
985
|
+
var templatePath;
|
|
986
|
+
var iosRoot;
|
|
987
|
+
var sceneDelegatePath;
|
|
988
|
+
var templateContent;
|
|
989
|
+
var existingContent;
|
|
990
|
+
|
|
991
|
+
/*
|
|
992
|
+
* The hook file is located under:
|
|
993
|
+
* plugin-root/scripts/mservice-deeplink-setup.js
|
|
994
|
+
*/
|
|
995
|
+
pluginRoot = path.resolve(
|
|
996
|
+
__dirname,
|
|
997
|
+
".."
|
|
998
|
+
);
|
|
999
|
+
|
|
1000
|
+
templatePath = path.join(
|
|
1001
|
+
pluginRoot,
|
|
1002
|
+
"templates",
|
|
1003
|
+
"ios",
|
|
1004
|
+
"SceneDelegate.swift"
|
|
1005
|
+
);
|
|
1006
|
+
|
|
1007
|
+
if (!fs.existsSync(templatePath)) {
|
|
1008
|
+
throw new Error(
|
|
1009
|
+
"SceneDelegate.swift template was not found: " +
|
|
1010
|
+
templatePath
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
iosRoot = path.join(
|
|
1015
|
+
projectRoot,
|
|
1016
|
+
"platforms",
|
|
1017
|
+
"ios"
|
|
1018
|
+
);
|
|
1019
|
+
|
|
1020
|
+
sceneDelegatePath = findFileRecursively(
|
|
1021
|
+
iosRoot,
|
|
1022
|
+
"SceneDelegate.swift"
|
|
1023
|
+
);
|
|
1024
|
+
|
|
1025
|
+
if (sceneDelegatePath === "") {
|
|
1026
|
+
throw new Error(
|
|
1027
|
+
"Generated SceneDelegate.swift was not found under: " +
|
|
1028
|
+
iosRoot
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
templateContent = fs.readFileSync(
|
|
1033
|
+
templatePath,
|
|
1034
|
+
"utf8"
|
|
1035
|
+
);
|
|
1036
|
+
|
|
1037
|
+
existingContent = fs.readFileSync(
|
|
1038
|
+
sceneDelegatePath,
|
|
1039
|
+
"utf8"
|
|
1040
|
+
);
|
|
1041
|
+
|
|
1042
|
+
if (existingContent === templateContent) {
|
|
1043
|
+
console.log(
|
|
1044
|
+
"[MService Deep Link] SceneDelegate.swift " +
|
|
1045
|
+
"already configured: " +
|
|
1046
|
+
sceneDelegatePath
|
|
1047
|
+
);
|
|
1048
|
+
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
fs.writeFileSync(
|
|
1053
|
+
sceneDelegatePath,
|
|
1054
|
+
templateContent,
|
|
1055
|
+
"utf8"
|
|
1056
|
+
);
|
|
1057
|
+
|
|
1058
|
+
console.log(
|
|
1059
|
+
"[MService Deep Link] SceneDelegate.swift configured: " +
|
|
1060
|
+
sceneDelegatePath
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
module.exports = function (context) {
|
|
1064
|
+
var options;
|
|
1065
|
+
var cordovaOptions;
|
|
1066
|
+
var platforms;
|
|
1067
|
+
var projectRoot;
|
|
1068
|
+
var configXmlPath;
|
|
1069
|
+
var configXml;
|
|
1070
|
+
var configuration;
|
|
1071
|
+
|
|
1072
|
+
try {
|
|
1073
|
+
options = context.opts || {};
|
|
1074
|
+
cordovaOptions = options.cordova || {};
|
|
1075
|
+
|
|
1076
|
+
platforms =
|
|
1077
|
+
options.platforms ||
|
|
1078
|
+
cordovaOptions.platforms ||
|
|
1079
|
+
[];
|
|
1080
|
+
|
|
1081
|
+
projectRoot = options.projectRoot || "";
|
|
1082
|
+
|
|
1083
|
+
if (projectRoot === "") {
|
|
1084
|
+
throw new Error(
|
|
1085
|
+
"Cordova project root could not be determined."
|
|
1086
|
+
);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
configXmlPath = path.join(projectRoot, "config.xml");
|
|
1090
|
+
|
|
1091
|
+
if (!fs.existsSync(configXmlPath)) {
|
|
1092
|
+
throw new Error(
|
|
1093
|
+
"config.xml was not found at: " + configXmlPath
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
configXml = fs.readFileSync(configXmlPath, "utf8");
|
|
1098
|
+
|
|
1099
|
+
configuration = {
|
|
1100
|
+
scheme: getPreferenceValue(
|
|
1101
|
+
configXml,
|
|
1102
|
+
"MServiceDeepLinkScheme"
|
|
1103
|
+
),
|
|
1104
|
+
host: getPreferenceValue(
|
|
1105
|
+
configXml,
|
|
1106
|
+
"MServiceDeepLinkHost"
|
|
1107
|
+
),
|
|
1108
|
+
path: normalizePath(
|
|
1109
|
+
getPreferenceValue(
|
|
1110
|
+
configXml,
|
|
1111
|
+
"MServiceDeepLinkPath"
|
|
1112
|
+
)
|
|
1113
|
+
),
|
|
1114
|
+
iosAssociatedDomain: getPreferenceValue(
|
|
1115
|
+
configXml,
|
|
1116
|
+
"MServiceIOSAssociatedDomain"
|
|
1117
|
+
)
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
validateConfiguration(configuration);
|
|
1121
|
+
|
|
1122
|
+
if (platforms.indexOf("android") !== -1) {
|
|
1123
|
+
configureAndroidAppLink(
|
|
1124
|
+
projectRoot,
|
|
1125
|
+
configuration
|
|
1126
|
+
);
|
|
1127
|
+
|
|
1128
|
+
configureAndroidMainActivity(
|
|
1129
|
+
projectRoot
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1132
|
+
if (platforms.indexOf("ios") !== -1) {
|
|
1133
|
+
configureIOSAssociatedDomains(
|
|
1134
|
+
projectRoot,
|
|
1135
|
+
configuration
|
|
1136
|
+
);
|
|
1137
|
+
|
|
1138
|
+
configureIOSSceneDelegate(
|
|
1139
|
+
projectRoot
|
|
1140
|
+
);
|
|
1141
|
+
}
|
|
1142
|
+
console.log("");
|
|
1143
|
+
console.log("================================================");
|
|
1144
|
+
console.log("[MService Deep Link] Configuration validated");
|
|
1145
|
+
console.log(
|
|
1146
|
+
"[MService Deep Link] Platforms: " +
|
|
1147
|
+
platforms.join(", ")
|
|
1148
|
+
);
|
|
1149
|
+
console.log(
|
|
1150
|
+
"[MService Deep Link] Scheme: " +
|
|
1151
|
+
configuration.scheme
|
|
1152
|
+
);
|
|
1153
|
+
console.log(
|
|
1154
|
+
"[MService Deep Link] Host: " +
|
|
1155
|
+
configuration.host
|
|
1156
|
+
);
|
|
1157
|
+
console.log(
|
|
1158
|
+
"[MService Deep Link] Path: " +
|
|
1159
|
+
configuration.path
|
|
1160
|
+
);
|
|
1161
|
+
console.log(
|
|
1162
|
+
"[MService Deep Link] iOS Associated Domain: " +
|
|
1163
|
+
(
|
|
1164
|
+
configuration.iosAssociatedDomain ||
|
|
1165
|
+
"Not configured"
|
|
1166
|
+
)
|
|
1167
|
+
);
|
|
1168
|
+
console.log("================================================");
|
|
1169
|
+
console.log("");
|
|
1170
|
+
|
|
1171
|
+
return Promise.resolve();
|
|
1172
|
+
} catch (exception) {
|
|
1173
|
+
console.error("");
|
|
1174
|
+
console.error(
|
|
1175
|
+
"[MService Deep Link] Hook failed: " +
|
|
1176
|
+
exception.message
|
|
1177
|
+
);
|
|
1178
|
+
console.error("");
|
|
1179
|
+
|
|
1180
|
+
return Promise.reject(exception);
|
|
1181
|
+
}
|
|
1182
|
+
};
|