nativescript 8.9.0-dev.2 → 8.9.0-dev.4
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/config/test-deps-versions-generated.json +1 -1
- package/docs/man_pages/project/configuration/widget-ios.md +24 -0
- package/docs/man_pages/project/configuration/widget.md +24 -0
- package/docs/man_pages/start.md +1 -1
- package/lib/android-tools-info.js +11 -22
- package/lib/base-package-manager.js +53 -70
- package/lib/bun-package-manager.js +75 -98
- package/lib/color.js +4 -4
- package/lib/commands/add-platform.js +14 -30
- package/lib/commands/apple-login.js +18 -29
- package/lib/commands/appstore-list.js +34 -45
- package/lib/commands/appstore-upload.js +54 -67
- package/lib/commands/build.js +55 -87
- package/lib/commands/clean.js +169 -184
- package/lib/commands/command-base.js +14 -27
- package/lib/commands/config.js +49 -68
- package/lib/commands/create-project.js +215 -234
- package/lib/commands/debug.js +66 -88
- package/lib/commands/deploy.js +28 -44
- package/lib/commands/embedding/embed.js +37 -56
- package/lib/commands/extensibility/install-extension.js +5 -16
- package/lib/commands/extensibility/list-extensions.js +13 -24
- package/lib/commands/extensibility/uninstall-extension.js +4 -15
- package/lib/commands/fonts.js +30 -41
- package/lib/commands/generate-assets.js +13 -28
- package/lib/commands/generate-help.js +2 -13
- package/lib/commands/generate.js +49 -60
- package/lib/commands/info.js +2 -13
- package/lib/commands/install.js +34 -49
- package/lib/commands/list-platforms.js +14 -25
- package/lib/commands/migrate.js +15 -26
- package/lib/commands/native-add.js +23 -46
- package/lib/commands/platform-clean.js +19 -32
- package/lib/commands/plugin/add-plugin.js +12 -25
- package/lib/commands/plugin/build-plugin.js +31 -44
- package/lib/commands/plugin/create-plugin.js +114 -137
- package/lib/commands/plugin/list-plugins.js +22 -33
- package/lib/commands/plugin/remove-plugin.js +21 -34
- package/lib/commands/plugin/update-plugin.js +20 -33
- package/lib/commands/post-install.js +25 -38
- package/lib/commands/prepare.js +19 -35
- package/lib/commands/preview.js +50 -63
- package/lib/commands/remove-platform.js +7 -18
- package/lib/commands/resources/resources-update.js +14 -27
- package/lib/commands/run.js +55 -76
- package/lib/commands/start.js +6 -19
- package/lib/commands/test-init.js +126 -137
- package/lib/commands/test.js +72 -95
- package/lib/commands/typings.js +126 -142
- package/lib/commands/update-platform.js +26 -39
- package/lib/commands/update.js +31 -44
- package/lib/commands/widget.js +408 -357
- package/lib/common/child-process.js +53 -72
- package/lib/common/codeGeneration/code-entity.js +1 -1
- package/lib/common/codeGeneration/code-printer.js +1 -1
- package/lib/common/command-params.js +7 -18
- package/lib/common/commands/analytics.js +29 -42
- package/lib/common/commands/autocompletion.js +41 -58
- package/lib/common/commands/device/device-log-stream.js +12 -23
- package/lib/common/commands/device/get-file.js +23 -34
- package/lib/common/commands/device/list-applications.js +12 -23
- package/lib/common/commands/device/list-devices.js +72 -87
- package/lib/common/commands/device/list-files.js +24 -35
- package/lib/common/commands/device/put-file.js +23 -34
- package/lib/common/commands/device/run-application.js +12 -25
- package/lib/common/commands/device/stop-application.js +11 -22
- package/lib/common/commands/device/uninstall-application.js +6 -17
- package/lib/common/commands/generate-messages.js +17 -28
- package/lib/common/commands/help.js +20 -33
- package/lib/common/commands/package-manager-get.js +6 -17
- package/lib/common/commands/package-manager-set.js +9 -20
- package/lib/common/commands/post-install.js +2 -13
- package/lib/common/commands/preuninstall.js +27 -42
- package/lib/common/commands/proxy/proxy-base.js +11 -22
- package/lib/common/commands/proxy/proxy-clear.js +4 -15
- package/lib/common/commands/proxy/proxy-get.js +3 -14
- package/lib/common/commands/proxy/proxy-set.js +87 -100
- package/lib/common/constants.js +11 -11
- package/lib/common/decorators.js +10 -22
- package/lib/common/dispatchers.js +84 -101
- package/lib/common/errors.js +92 -107
- package/lib/common/file-system.js +110 -132
- package/lib/common/header.js +1 -2
- package/lib/common/helpers.js +149 -178
- package/lib/common/host-info.js +40 -53
- package/lib/common/http-client.js +104 -119
- package/lib/common/logger/appenders/cli-appender.js +1 -2
- package/lib/common/logger/appenders/emit-appender.js +1 -2
- package/lib/common/logger/layouts/cli-layout.js +1 -2
- package/lib/common/logger/logger.js +4 -4
- package/lib/common/mobile/android/android-application-manager.js +138 -159
- package/lib/common/mobile/android/android-debug-bridge-result-handler.js +1 -1
- package/lib/common/mobile/android/android-debug-bridge.js +92 -117
- package/lib/common/mobile/android/android-device-file-system.js +101 -134
- package/lib/common/mobile/android/android-device-hash-service.js +52 -77
- package/lib/common/mobile/android/android-device.js +73 -90
- package/lib/common/mobile/android/android-emulator-services.js +105 -130
- package/lib/common/mobile/android/android-log-filter.js +1 -1
- package/lib/common/mobile/android/android-virtual-device-service.js +78 -99
- package/lib/common/mobile/android/device-android-debug-bridge.js +13 -29
- package/lib/common/mobile/android/genymotion/genymotion-service.js +94 -121
- package/lib/common/mobile/android/genymotion/virtualbox-service.js +74 -91
- package/lib/common/mobile/android/logcat-helper.js +114 -133
- package/lib/common/mobile/application-manager-base.js +89 -112
- package/lib/common/mobile/device-log-provider-base.js +7 -18
- package/lib/common/mobile/ios/device/ios-application-manager.js +79 -108
- package/lib/common/mobile/ios/device/ios-device-file-system.js +78 -105
- package/lib/common/mobile/ios/device/ios-device-operations.js +106 -143
- package/lib/common/mobile/ios/device/ios-device.js +20 -36
- package/lib/common/mobile/ios/ios-device-base.js +58 -81
- package/lib/common/mobile/ios/simulator/ios-emulator-services.js +66 -95
- package/lib/common/mobile/ios/simulator/ios-sim-resolver.js +1 -1
- package/lib/common/mobile/ios/simulator/ios-simulator-application-manager.js +61 -90
- package/lib/common/mobile/ios/simulator/ios-simulator-device.js +31 -47
- package/lib/common/mobile/ios/simulator/ios-simulator-file-system.js +37 -62
- package/lib/common/mobile/ios/simulator/ios-simulator-log-provider.js +24 -35
- package/lib/common/mobile/mobile-core/android-device-discovery.js +44 -63
- package/lib/common/mobile/mobile-core/android-emulator-discovery.js +23 -34
- package/lib/common/mobile/mobile-core/android-process-service.js +174 -213
- package/lib/common/mobile/mobile-core/device-discovery.js +2 -13
- package/lib/common/mobile/mobile-core/devices-service.js +400 -450
- package/lib/common/mobile/mobile-core/ios-device-discovery.js +25 -36
- package/lib/common/mobile/mobile-core/ios-simulator-discovery.js +49 -64
- package/lib/common/mobile/mobile-helper.js +15 -26
- package/lib/common/mobile/wp8/wp8-emulator-services.js +25 -52
- package/lib/common/opener.js +2 -2
- package/lib/common/prompter.js +91 -106
- package/lib/common/queue.js +9 -20
- package/lib/common/services/auto-completion-service.js +40 -53
- package/lib/common/services/cancellation.js +17 -28
- package/lib/common/services/commands-service.js +156 -179
- package/lib/common/services/help-service.js +130 -155
- package/lib/common/services/hooks-service.js +99 -114
- package/lib/common/services/ios-notification-service.js +21 -34
- package/lib/common/services/json-file-settings-service.js +56 -75
- package/lib/common/services/lock-service.js +35 -52
- package/lib/common/services/message-contract-generator.js +35 -46
- package/lib/common/services/micro-templating-service.js +6 -17
- package/lib/common/services/net-service.js +92 -109
- package/lib/common/services/project-files-manager.js +10 -23
- package/lib/common/services/proxy-service.js +13 -24
- package/lib/common/services/qr.js +13 -24
- package/lib/common/services/settings-service.js +1 -1
- package/lib/common/services/xcode-select-service.js +20 -35
- package/lib/common/utils.js +2 -2
- package/lib/common/validators/project-name-validator.js +1 -1
- package/lib/common/validators/validation-result.js +1 -1
- package/lib/common/verify-node-version.js +2 -3
- package/lib/common/yok.js +25 -38
- package/lib/config.js +41 -56
- package/lib/constants.js +24 -24
- package/lib/controllers/build-controller.js +82 -99
- package/lib/controllers/debug-controller.js +111 -132
- package/lib/controllers/deploy-controller.js +15 -23
- package/lib/controllers/migrate-controller.js +780 -853
- package/lib/controllers/platform-controller.js +74 -89
- package/lib/controllers/prepare-controller.js +241 -270
- package/lib/controllers/run-controller.js +411 -425
- package/lib/controllers/update-controller-base.js +16 -29
- package/lib/controllers/update-controller.js +101 -126
- package/lib/data/prepare-data.js +4 -1
- package/lib/definitions/project.d.ts +24 -24
- package/lib/detached-processes/cleanup-js-subprocess.js +3 -12
- package/lib/detached-processes/cleanup-process.js +16 -25
- package/lib/device-path-provider.js +23 -34
- package/lib/device-sockets/ios/app-debug-socket-proxy-factory.js +155 -170
- package/lib/device-sockets/ios/notification.js +1 -1
- package/lib/device-sockets/ios/socket-request-executor.js +26 -41
- package/lib/helpers/android-bundle-validator-helper.js +1 -1
- package/lib/helpers/deploy-command-helper.js +44 -49
- package/lib/helpers/key-command-helper.js +4 -13
- package/lib/helpers/livesync-command-helper.js +138 -153
- package/lib/helpers/network-connectivity-validator.js +6 -17
- package/lib/helpers/options-track-helper.js +6 -17
- package/lib/helpers/platform-command-helper.js +103 -124
- package/lib/key-commands/index.js +150 -200
- package/lib/nativescript-cli.js +5 -14
- package/lib/node-package-manager.js +90 -113
- package/lib/options.js +4 -13
- package/lib/package-installation-manager.js +132 -167
- package/lib/package-manager.js +64 -87
- package/lib/platform-command-param.js +4 -15
- package/lib/pnpm-package-manager.js +60 -79
- package/lib/project-data.js +1 -1
- package/lib/providers/project-files-provider.js +1 -1
- package/lib/services/analytics/analytics-broker-process.js +13 -22
- package/lib/services/analytics/analytics-broker.js +17 -30
- package/lib/services/analytics/analytics-service.js +165 -201
- package/lib/services/analytics/google-analytics-provider.js +41 -56
- package/lib/services/analytics-settings-service.js +15 -32
- package/lib/services/android/android-bundle-tool-service.js +43 -60
- package/lib/services/android/gradle-build-args-service.js +10 -21
- package/lib/services/android/gradle-build-service.js +22 -35
- package/lib/services/android/gradle-command-service.js +22 -35
- package/lib/services/android-device-debug-service.js +92 -119
- package/lib/services/android-plugin-build-service.js +219 -245
- package/lib/services/android-project-service.js +134 -179
- package/lib/services/android-resources-migration-service.js +57 -70
- package/lib/services/apple-portal/apple-portal-application-service.js +46 -63
- package/lib/services/apple-portal/apple-portal-session-service.js +196 -215
- package/lib/services/apple-portal/srp/srp-wrapper.js +45 -60
- package/lib/services/assets-generation/assets-generation-service.js +114 -128
- package/lib/services/build-artifacts-service.js +9 -20
- package/lib/services/build-info-file-service.js +20 -35
- package/lib/services/cleanup-service.js +47 -76
- package/lib/services/cocoapods-service.js +124 -145
- package/lib/services/device/device-install-app-service.js +54 -71
- package/lib/services/doctor-service.js +106 -125
- package/lib/services/extensibility-service.js +87 -106
- package/lib/services/files-hash-service.js +26 -43
- package/lib/services/hmr-status-service.js +1 -1
- package/lib/services/initialize-service.js +38 -51
- package/lib/services/ios/export-options-plist-service.js +41 -54
- package/lib/services/ios/ios-signing-service.js +171 -190
- package/lib/services/ios/spm-service.js +52 -65
- package/lib/services/ios/xcodebuild-args-service.js +77 -94
- package/lib/services/ios/xcodebuild-command-service.js +14 -25
- package/lib/services/ios/xcodebuild-service.js +52 -71
- package/lib/services/ios-debugger-port-service.js +24 -37
- package/lib/services/ios-device-debug-service.js +75 -102
- package/lib/services/ios-entitlements-service.js +31 -42
- package/lib/services/ios-extensions-service.js +18 -29
- package/lib/services/ios-project-service.js +530 -591
- package/lib/services/ios-provision-service.js +110 -131
- package/lib/services/ios-watch-app-service.js +21 -32
- package/lib/services/ip-service.js +39 -54
- package/lib/services/itmstransporter-service.js +129 -152
- package/lib/services/livesync/android-device-livesync-service-base.js +31 -48
- package/lib/services/livesync/android-device-livesync-service.js +121 -150
- package/lib/services/livesync/android-device-livesync-sockets-service.js +123 -154
- package/lib/services/livesync/android-livesync-service.js +14 -35
- package/lib/services/livesync/android-livesync-tool.js +90 -113
- package/lib/services/livesync/device-livesync-service-base.js +16 -29
- package/lib/services/livesync/ios-device-livesync-service.js +120 -149
- package/lib/services/livesync/ios-livesync-service.js +43 -59
- package/lib/services/livesync/platform-livesync-service-base.js +98 -123
- package/lib/services/log-parser-service.js +1 -1
- package/lib/services/log-source-map-service.js +31 -42
- package/lib/services/marking-mode-service.js +17 -30
- package/lib/services/npm-config-service.js +1 -1
- package/lib/services/pacote-service.js +54 -69
- package/lib/services/performance-service.js +1 -1
- package/lib/services/platform/add-platform-service.js +57 -78
- package/lib/services/platform/platform-validation-service.js +22 -33
- package/lib/services/platform/prepare-native-platform-service.js +51 -64
- package/lib/services/platform-environment-requirements.js +27 -38
- package/lib/services/plugins-service.js +126 -151
- package/lib/services/project-backup-service.js +1 -1
- package/lib/services/project-changes-service.js +126 -143
- package/lib/services/project-cleanup-service.js +65 -78
- package/lib/services/project-config-service.js +78 -88
- package/lib/services/project-data-service.js +112 -129
- package/lib/services/project-name-service.js +28 -43
- package/lib/services/project-service.js +90 -109
- package/lib/services/project-templates-service.js +52 -67
- package/lib/services/start-service.js +41 -59
- package/lib/services/temp-service.js +8 -21
- package/lib/services/terminal-spinner-service.js +15 -26
- package/lib/services/test-execution-service.js +64 -77
- package/lib/services/test-initialization-service.js +2 -2
- package/lib/services/timeline-profiler-service.js +1 -1
- package/lib/services/versions-service.js +120 -139
- package/lib/services/webpack/webpack-compiler-service.js +228 -251
- package/lib/services/xcconfig-service.js +8 -19
- package/lib/sys-info.js +45 -62
- package/lib/tools/node-modules/node-modules-builder.js +16 -27
- package/lib/yarn-package-manager.js +59 -78
- package/lib/yarn2-package-manager.js +62 -81
- package/package.json +67 -82
- package/node_modules/@npmcli/move-file/LICENSE.md +0 -22
- package/node_modules/@npmcli/move-file/README.md +0 -69
- package/node_modules/@npmcli/move-file/lib/index.js +0 -185
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/LICENSE +0 -21
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/bin/cmd.js +0 -68
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/index.js +0 -31
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/lib/find-made.js +0 -29
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/lib/mkdirp-manual.js +0 -64
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/lib/mkdirp-native.js +0 -39
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/lib/opts-arg.js +0 -23
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/lib/path-arg.js +0 -29
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/lib/use-native.js +0 -10
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/package.json +0 -44
- package/node_modules/@npmcli/move-file/node_modules/mkdirp/readme.markdown +0 -266
- package/node_modules/@npmcli/move-file/package.json +0 -47
- package/node_modules/balanced-match/.github/FUNDING.yml +0 -2
- package/node_modules/balanced-match/LICENSE.md +0 -21
- package/node_modules/balanced-match/README.md +0 -97
- package/node_modules/balanced-match/index.js +0 -62
- package/node_modules/balanced-match/package.json +0 -48
- package/node_modules/concat-map/.travis.yml +0 -4
- package/node_modules/concat-map/LICENSE +0 -18
- package/node_modules/concat-map/README.markdown +0 -62
- package/node_modules/concat-map/example/map.js +0 -6
- package/node_modules/concat-map/index.js +0 -13
- package/node_modules/concat-map/package.json +0 -43
- package/node_modules/concat-map/test/map.js +0 -39
- package/node_modules/fs.realpath/LICENSE +0 -43
- package/node_modules/fs.realpath/README.md +0 -33
- package/node_modules/fs.realpath/index.js +0 -66
- package/node_modules/fs.realpath/old.js +0 -303
- package/node_modules/fs.realpath/package.json +0 -26
- package/node_modules/inflight/LICENSE +0 -15
- package/node_modules/inflight/README.md +0 -37
- package/node_modules/inflight/inflight.js +0 -54
- package/node_modules/inflight/package.json +0 -29
- package/node_modules/inherits/LICENSE +0 -16
- package/node_modules/inherits/README.md +0 -42
- package/node_modules/inherits/inherits.js +0 -9
- package/node_modules/inherits/inherits_browser.js +0 -27
- package/node_modules/inherits/package.json +0 -29
- package/node_modules/once/LICENSE +0 -15
- package/node_modules/once/README.md +0 -79
- package/node_modules/once/once.js +0 -42
- package/node_modules/once/package.json +0 -33
- package/node_modules/path-is-absolute/index.js +0 -20
- package/node_modules/path-is-absolute/license +0 -21
- package/node_modules/path-is-absolute/package.json +0 -43
- package/node_modules/path-is-absolute/readme.md +0 -59
- package/node_modules/rimraf/LICENSE +0 -15
- package/node_modules/rimraf/README.md +0 -101
- package/node_modules/rimraf/bin.js +0 -68
- package/node_modules/rimraf/node_modules/brace-expansion/LICENSE +0 -21
- package/node_modules/rimraf/node_modules/brace-expansion/README.md +0 -129
- package/node_modules/rimraf/node_modules/brace-expansion/index.js +0 -201
- package/node_modules/rimraf/node_modules/brace-expansion/package.json +0 -47
- package/node_modules/rimraf/node_modules/glob/LICENSE +0 -21
- package/node_modules/rimraf/node_modules/glob/README.md +0 -378
- package/node_modules/rimraf/node_modules/glob/common.js +0 -238
- package/node_modules/rimraf/node_modules/glob/glob.js +0 -790
- package/node_modules/rimraf/node_modules/glob/package.json +0 -55
- package/node_modules/rimraf/node_modules/glob/sync.js +0 -486
- package/node_modules/rimraf/node_modules/minimatch/LICENSE +0 -15
- package/node_modules/rimraf/node_modules/minimatch/README.md +0 -230
- package/node_modules/rimraf/node_modules/minimatch/minimatch.js +0 -947
- package/node_modules/rimraf/node_modules/minimatch/package.json +0 -33
- package/node_modules/rimraf/package.json +0 -32
- package/node_modules/rimraf/rimraf.js +0 -360
- package/node_modules/stringify-package/LICENSE +0 -13
- package/node_modules/stringify-package/README.md +0 -55
- package/node_modules/stringify-package/index.js +0 -18
- package/node_modules/stringify-package/package.json +0 -38
- package/node_modules/wrappy/LICENSE +0 -15
- package/node_modules/wrappy/README.md +0 -36
- package/node_modules/wrappy/package.json +0 -29
- package/node_modules/wrappy/wrappy.js +0 -33
package/lib/commands/widget.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.WidgetIOSCommand = exports.WidgetCommand = void 0;
|
|
13
4
|
const fs = require("fs");
|
|
@@ -26,20 +17,16 @@ class WidgetCommand {
|
|
|
26
17
|
this.allowedParameters = [];
|
|
27
18
|
this.$projectData.initializeProjectData();
|
|
28
19
|
}
|
|
29
|
-
execute(args) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return Promise.resolve();
|
|
33
|
-
});
|
|
20
|
+
async execute(args) {
|
|
21
|
+
this.failWithUsage();
|
|
22
|
+
return Promise.resolve();
|
|
34
23
|
}
|
|
35
24
|
failWithUsage() {
|
|
36
25
|
this.$errors.failWithHelp("Usage: ns widget ios");
|
|
37
26
|
}
|
|
38
|
-
canExecute(args) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return false;
|
|
42
|
-
});
|
|
27
|
+
async canExecute(args) {
|
|
28
|
+
this.failWithUsage();
|
|
29
|
+
return false;
|
|
43
30
|
}
|
|
44
31
|
getIosSourcePathBase() {
|
|
45
32
|
const resources = this.$projectData.getAppResourcesDirectoryPath();
|
|
@@ -51,77 +38,64 @@ class WidgetIOSCommand extends WidgetCommand {
|
|
|
51
38
|
constructor($projectData, $projectConfigService, $logger, $errors) {
|
|
52
39
|
super($projectData, $projectConfigService, $logger, $errors);
|
|
53
40
|
}
|
|
54
|
-
canExecute(args) {
|
|
55
|
-
return
|
|
56
|
-
return true;
|
|
57
|
-
});
|
|
41
|
+
async canExecute(args) {
|
|
42
|
+
return true;
|
|
58
43
|
}
|
|
59
|
-
execute(args) {
|
|
60
|
-
|
|
61
|
-
this.startPrompt(args);
|
|
62
|
-
});
|
|
44
|
+
async execute(args) {
|
|
45
|
+
this.startPrompt(args);
|
|
63
46
|
}
|
|
64
|
-
startPrompt(args) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
initial: 1,
|
|
94
|
-
});
|
|
95
|
-
switch (result.value) {
|
|
96
|
-
case 0:
|
|
97
|
-
this.$logger.info("TODO");
|
|
98
|
-
break;
|
|
99
|
-
case 1:
|
|
100
|
-
yield this.generateSharedWidgetPackage(this.$projectData.projectDir, name);
|
|
101
|
-
this.generateWidget(this.$projectData.projectDir, name, result.value);
|
|
102
|
-
this.generateAppleUtility(this.$projectData.projectDir, name);
|
|
103
|
-
break;
|
|
104
|
-
case 2:
|
|
105
|
-
this.$logger.info("TODO");
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
47
|
+
async startPrompt(args) {
|
|
48
|
+
let result = await prompts.prompt({
|
|
49
|
+
type: "text",
|
|
50
|
+
name: "name",
|
|
51
|
+
message: `What name would you like for this widget? (Default is 'widget')`,
|
|
52
|
+
});
|
|
53
|
+
const name = (result.name || "widget").toLowerCase();
|
|
54
|
+
result = await prompts.prompt({
|
|
55
|
+
type: "select",
|
|
56
|
+
name: "value",
|
|
57
|
+
message: `What type of widget would you like?`,
|
|
58
|
+
choices: [
|
|
59
|
+
{
|
|
60
|
+
title: "Live Activity",
|
|
61
|
+
description: "This will create a Live Activity that will display on the iOS Lock Screen.",
|
|
62
|
+
value: 0,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
title: "Live Activity with Home Screen Widget",
|
|
66
|
+
description: "This will create a Live Activity that will display on the iOS Lock Screen with ability to also display a Home Screen Widget.",
|
|
67
|
+
value: 1,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
title: "Home Screen Widget",
|
|
71
|
+
description: "This will create just a Home Screen Widget.",
|
|
72
|
+
value: 2,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
initial: 1,
|
|
108
76
|
});
|
|
77
|
+
const bundleId = this.$projectConfigService.getValue(`id`, "");
|
|
78
|
+
if ([0, 1].includes(result.value)) {
|
|
79
|
+
// shared model only needed with live activities
|
|
80
|
+
await this.generateSharedWidgetPackage(this.$projectData.projectDir, name);
|
|
81
|
+
}
|
|
82
|
+
this.generateWidget(this.$projectData.projectDir, name, bundleId, result.value);
|
|
83
|
+
this.generateAppleUtility(this.$projectData.projectDir, name, bundleId, result.value);
|
|
109
84
|
}
|
|
110
|
-
generateSharedWidgetPackage(projectDir, name) {
|
|
85
|
+
async generateSharedWidgetPackage(projectDir, name) {
|
|
111
86
|
var _a;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
let content = `// swift-tools-version:5.9
|
|
87
|
+
const sharedWidgetDir = "Shared_Resources/iOS/SharedWidget";
|
|
88
|
+
const sharedWidgetPath = path.join(projectDir, sharedWidgetDir);
|
|
89
|
+
const sharedWidgetSourceDir = "Sources/SharedWidget";
|
|
90
|
+
const sharedWidgetPackagePath = path.join(projectDir, `${sharedWidgetDir}/Package.swift`);
|
|
91
|
+
const sharedWidgetSourcePath = path.join(sharedWidgetPath, `${sharedWidgetSourceDir}/${(0, utils_1.capitalizeFirstLetter)(name)}Model.swift`);
|
|
92
|
+
const gitIgnorePath = path.join(projectDir, ".gitignore");
|
|
93
|
+
if (!fs.existsSync(sharedWidgetPackagePath)) {
|
|
94
|
+
fs.mkdirSync(sharedWidgetPath, { recursive: true });
|
|
95
|
+
fs.mkdirSync(path.join(sharedWidgetPath, sharedWidgetSourceDir), {
|
|
96
|
+
recursive: true,
|
|
97
|
+
});
|
|
98
|
+
let content = `// swift-tools-version:5.9
|
|
125
99
|
import PackageDescription
|
|
126
100
|
|
|
127
101
|
let package = Package(
|
|
@@ -144,8 +118,8 @@ let package = Package(
|
|
|
144
118
|
)
|
|
145
119
|
]
|
|
146
120
|
)${os_1.EOL}`;
|
|
147
|
-
|
|
148
|
-
|
|
121
|
+
fs.writeFileSync(sharedWidgetPackagePath, content);
|
|
122
|
+
content = `import ActivityKit
|
|
149
123
|
import WidgetKit
|
|
150
124
|
|
|
151
125
|
public struct ${(0, utils_1.capitalizeFirstLetter)(name)}Model: ActivityAttributes {
|
|
@@ -153,12 +127,12 @@ public struct ${(0, utils_1.capitalizeFirstLetter)(name)}Model: ActivityAttribut
|
|
|
153
127
|
|
|
154
128
|
public struct ContentState: Codable, Hashable {
|
|
155
129
|
// Dynamic stateful properties about your activity go here!
|
|
156
|
-
public var
|
|
157
|
-
public var
|
|
130
|
+
public var message: String
|
|
131
|
+
public var deliveryTime: Double
|
|
158
132
|
|
|
159
|
-
public init(
|
|
160
|
-
self.
|
|
161
|
-
self.
|
|
133
|
+
public init(message: String, deliveryTime: Double) {
|
|
134
|
+
self.message = message
|
|
135
|
+
self.deliveryTime = deliveryTime
|
|
162
136
|
}
|
|
163
137
|
}
|
|
164
138
|
|
|
@@ -171,52 +145,51 @@ public struct ${(0, utils_1.capitalizeFirstLetter)(name)}Model: ActivityAttribut
|
|
|
171
145
|
self.totalAmount = totalAmount
|
|
172
146
|
}
|
|
173
147
|
}${os_1.EOL}`;
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
148
|
+
fs.writeFileSync(sharedWidgetSourcePath, content);
|
|
149
|
+
// update spm package
|
|
150
|
+
const configData = this.$projectConfigService.readConfig(projectDir);
|
|
151
|
+
if (!configData.ios) {
|
|
152
|
+
configData.ios = {};
|
|
153
|
+
}
|
|
154
|
+
if (!configData.ios.SPMPackages) {
|
|
155
|
+
configData.ios.SPMPackages = [];
|
|
156
|
+
}
|
|
157
|
+
const spmPackages = configData.ios.SPMPackages;
|
|
158
|
+
const sharedWidgetPackage = spmPackages === null || spmPackages === void 0 ? void 0 : spmPackages.find((p) => p.name === "SharedWidget");
|
|
159
|
+
if (!sharedWidgetPackage) {
|
|
160
|
+
spmPackages.push({
|
|
161
|
+
name: "SharedWidget",
|
|
162
|
+
libs: ["SharedWidget"],
|
|
163
|
+
path: "./Shared_Resources/iOS/SharedWidget",
|
|
164
|
+
// @ts-ignore
|
|
165
|
+
targets: [name],
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
// add target if needed
|
|
170
|
+
if (!((_a = sharedWidgetPackage.targets) === null || _a === void 0 ? void 0 : _a.includes(name))) {
|
|
171
|
+
sharedWidgetPackage.targets.push(name);
|
|
199
172
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
173
|
+
}
|
|
174
|
+
configData.ios.SPMPackages = spmPackages;
|
|
175
|
+
await this.$projectConfigService.setValue("", // root
|
|
176
|
+
configData);
|
|
177
|
+
if (fs.existsSync(gitIgnorePath)) {
|
|
178
|
+
const gitIgnore = fs.readFileSync(gitIgnorePath, {
|
|
179
|
+
encoding: "utf-8",
|
|
180
|
+
});
|
|
181
|
+
const swiftBuildIgnore = `# Swift
|
|
208
182
|
.build
|
|
209
183
|
.swiftpm`;
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
184
|
+
if (gitIgnore.indexOf(swiftBuildIgnore) === -1) {
|
|
185
|
+
content = `${gitIgnore}${os_1.EOL}${swiftBuildIgnore}${os_1.EOL}`;
|
|
186
|
+
fs.writeFileSync(gitIgnorePath, content);
|
|
214
187
|
}
|
|
215
|
-
console.log(`\nCreated Shared Resources: ${sharedWidgetDir}.\n`);
|
|
216
188
|
}
|
|
217
|
-
|
|
189
|
+
console.log(`\nCreated Shared Resources: ${sharedWidgetDir}.\n`);
|
|
190
|
+
}
|
|
218
191
|
}
|
|
219
|
-
generateWidget(projectDir, name, type) {
|
|
192
|
+
generateWidget(projectDir, name, bundleId, type) {
|
|
220
193
|
const appResourcePath = this.$projectData.appResourcesDirectoryPath;
|
|
221
194
|
const capitalName = (0, utils_1.capitalizeFirstLetter)(name);
|
|
222
195
|
const appInfoPlistPath = path.join(appResourcePath, "iOS", "Info.plist");
|
|
@@ -230,7 +203,7 @@ public struct ${(0, utils_1.capitalizeFirstLetter)(name)}Model: ActivityAttribut
|
|
|
230
203
|
const widgetBundlePath = path.join(widgetPath, `${capitalName}Bundle.swift`);
|
|
231
204
|
const widgetHomeScreenPath = path.join(widgetPath, `${capitalName}HomeScreenWidget.swift`);
|
|
232
205
|
const widgetLiveActivityPath = path.join(widgetPath, `${capitalName}LiveActivity.swift`);
|
|
233
|
-
const appIntentPath = path.join(widgetPath, `AppIntent.swift`);
|
|
206
|
+
// const appIntentPath = path.join(widgetPath, `AppIntent.swift`);
|
|
234
207
|
// const widgetLockScreenControlPath = path.join(
|
|
235
208
|
// widgetPath,
|
|
236
209
|
// `${capitalName}LockScreenControl.swift`
|
|
@@ -247,6 +220,10 @@ public struct ${(0, utils_1.capitalizeFirstLetter)(name)}Model: ActivityAttribut
|
|
|
247
220
|
<key>NSExtensionPointIdentifier</key>
|
|
248
221
|
<string>com.apple.widgetkit-extension</string>
|
|
249
222
|
</dict>
|
|
223
|
+
<key>CFBundleShortVersionString</key>
|
|
224
|
+
<string>1.0</string>
|
|
225
|
+
<key>CFBundleVersion</key>
|
|
226
|
+
<string>1.0</string>
|
|
250
227
|
</dict>
|
|
251
228
|
</plist>${os_1.EOL}`;
|
|
252
229
|
fs.writeFileSync(extensionsInfoPath, content);
|
|
@@ -278,117 +255,124 @@ public struct ${(0, utils_1.capitalizeFirstLetter)(name)}Model: ActivityAttribut
|
|
|
278
255
|
import SwiftUI
|
|
279
256
|
|
|
280
257
|
@main
|
|
281
|
-
struct ${capitalName}Bundle: WidgetBundle {
|
|
258
|
+
struct ${capitalName}Bundle: SwiftUI.WidgetBundle {
|
|
282
259
|
var body: some Widget {
|
|
283
260
|
${[1, 2].includes(type) ? capitalName + "HomeScreenWidget()" : ""}
|
|
284
261
|
${[0, 1].includes(type) ? capitalName + "LiveActivity()" : ""}
|
|
285
262
|
}
|
|
286
263
|
}${os_1.EOL}`;
|
|
287
264
|
fs.writeFileSync(widgetBundlePath, content);
|
|
288
|
-
content = `import WidgetKit
|
|
289
|
-
import AppIntents
|
|
290
|
-
|
|
291
|
-
struct ConfigurationAppIntent: WidgetConfigurationIntent {
|
|
292
|
-
static var title: LocalizedStringResource { "Pizza Delivery" }
|
|
293
|
-
static var description: IntentDescription { "Get up to date delivery details" }
|
|
294
|
-
|
|
295
|
-
// An example configurable parameter.
|
|
296
|
-
@Parameter(title: "Favorite Pizza", default: "🍕")
|
|
297
|
-
var favoritePizza: String
|
|
298
|
-
|
|
299
|
-
@Parameter(title: "Random", default: "Hello")
|
|
300
|
-
var random: String
|
|
301
|
-
}${os_1.EOL}`;
|
|
302
|
-
fs.writeFileSync(appIntentPath, content);
|
|
303
265
|
if ([0, 1].includes(type)) {
|
|
304
266
|
content = `import ActivityKit
|
|
305
267
|
import SwiftUI
|
|
306
268
|
import WidgetKit
|
|
307
269
|
import Foundation
|
|
308
270
|
import SharedWidget
|
|
271
|
+
import os
|
|
309
272
|
|
|
310
273
|
struct ${capitalName}LiveActivity: Widget {
|
|
311
|
-
var body: some WidgetConfiguration {
|
|
312
|
-
ActivityConfiguration(for: ${capitalName}Model.self) { context in
|
|
313
|
-
// Lock screen/banner UI goes here
|
|
314
|
-
ContentView(driver: context.state.driverName)
|
|
315
|
-
.activityBackgroundTint(Color.black)
|
|
316
|
-
.activitySystemActionForegroundColor(Color.white)
|
|
317
|
-
|
|
318
|
-
} dynamicIsland: { context in
|
|
319
|
-
DynamicIsland {
|
|
320
|
-
// Expanded UI goes here. Compose the expanded UI through
|
|
321
|
-
// various regions, like leading/trailing/center/bottom
|
|
322
|
-
DynamicIslandExpandedRegion(.leading) {
|
|
323
|
-
if let timeLeft = timeLeft(range1: Date(), range2: context.state.estimatedDeliveryTime) {
|
|
324
|
-
Image(systemName: "car")
|
|
325
|
-
.resizable()
|
|
326
|
-
.scaledToFit()
|
|
327
|
-
.frame(width: 50, height: 50) // Adjust size
|
|
328
|
-
.foregroundColor(timeLeft <= 1000 ? Color.green : Color.orange)
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
DynamicIslandExpandedRegion(.trailing) {
|
|
332
|
-
if let timeLeft = timeLeft(range1: Date(), range2: context.state.estimatedDeliveryTime) {
|
|
333
|
-
ProgressView(value: timeLeft, total: 3600)
|
|
334
|
-
.progressViewStyle(.circular)
|
|
335
|
-
.tint(timeLeft <= 1000 ? Color.green : Color.orange)
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
DynamicIslandExpandedRegion(.bottom) {
|
|
339
|
-
if let timeLeft = timeLeft(range1: Date(), range2: context.state.estimatedDeliveryTime) {
|
|
340
|
-
Text("\\(context.state.driverName) \\(timeLeft <= 0 ? "has arrived!" : String(format: "is %.1f min away", timeLeft / 60))")
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
} compactLeading: {
|
|
344
|
-
if let timeLeft = timeLeft(range1: Date(), range2: context.state.estimatedDeliveryTime) {
|
|
345
|
-
Image(systemName: "car")
|
|
346
|
-
.resizable()
|
|
347
|
-
.scaledToFit()
|
|
348
|
-
.frame(width: 20, height: 20)
|
|
349
|
-
.foregroundColor(timeLeft <= 0 ? .green : .orange)
|
|
350
|
-
}
|
|
351
|
-
} compactTrailing: {
|
|
352
|
-
if let timeLeft = timeLeft(range1: Date(), range2: context.state.estimatedDeliveryTime) {
|
|
353
|
-
Image(systemName: "timer.circle.fill")
|
|
354
|
-
.resizable()
|
|
355
|
-
.scaledToFit()
|
|
356
|
-
.frame(width: 20, height: 20)
|
|
357
|
-
.foregroundColor(timeLeft <= 0 ? .green : .orange)
|
|
358
|
-
}
|
|
359
|
-
} minimal: {
|
|
360
|
-
Text(context.state.driverName).font(.system(size: 12))
|
|
361
|
-
}
|
|
362
|
-
.widgetURL(URL(string: "http://www.apple.com"))
|
|
363
|
-
.keylineTint(Color.red)
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
274
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
275
|
+
var body: some WidgetConfiguration {
|
|
276
|
+
ActivityConfiguration(for: ${capitalName}Model.self) { context in
|
|
277
|
+
|
|
278
|
+
LockScreenView(message: context.state.message, deliveryTime: context.state.deliveryTime)
|
|
279
|
+
.activityBackgroundTint(Color.black)
|
|
280
|
+
.activitySystemActionForegroundColor(Color.white)
|
|
281
|
+
|
|
282
|
+
} dynamicIsland: { context in
|
|
283
|
+
DynamicIsland {
|
|
284
|
+
DynamicIslandExpandedRegion(.leading) {
|
|
285
|
+
Image(systemName: context.state.deliveryTime >= 0 ? "car.side.arrowtriangle.up.fill" : "face.smiling.inverse")
|
|
286
|
+
.resizable()
|
|
287
|
+
.scaledToFit()
|
|
288
|
+
.frame(width: 50, height: 50)
|
|
289
|
+
.foregroundColor(context.state.deliveryTime >= 0 ? Color.green : Color.blue)
|
|
290
|
+
}
|
|
291
|
+
DynamicIslandExpandedRegion(.trailing) {
|
|
292
|
+
if (context.state.deliveryTime >= 0) {
|
|
293
|
+
ZStack {
|
|
294
|
+
ProgressView(value: context.state.deliveryTime, total: 60)
|
|
295
|
+
.progressViewStyle(.circular)
|
|
296
|
+
.tint(Color.green)
|
|
297
|
+
.frame(width: 75, height: 75)
|
|
298
|
+
Text("\\(formatter.string(for: context.state.deliveryTime) ?? "") mins")
|
|
299
|
+
.font(.system(size: 11))
|
|
300
|
+
.foregroundStyle(.white)
|
|
301
|
+
}.frame(width: 75, height: 75)
|
|
302
|
+
} else {
|
|
303
|
+
Image(systemName: "checkmark.circle.fill")
|
|
304
|
+
.resizable()
|
|
305
|
+
.scaledToFit()
|
|
306
|
+
.frame(width: 50, height: 50)
|
|
307
|
+
.foregroundColor(.blue)
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
DynamicIslandExpandedRegion(.bottom) {
|
|
311
|
+
Text("\\(context.state.message)")
|
|
312
|
+
}
|
|
313
|
+
} compactLeading: {
|
|
314
|
+
Image(systemName: context.state.deliveryTime >= 0 ? "car.side.arrowtriangle.up.fill" : "face.smiling.inverse")
|
|
315
|
+
.resizable()
|
|
316
|
+
.scaledToFit()
|
|
317
|
+
.frame(width: 20, height: 20)
|
|
318
|
+
.foregroundColor(context.state.deliveryTime >= 0 ? .green : .blue)
|
|
319
|
+
} compactTrailing: {
|
|
320
|
+
Image(systemName: context.state.deliveryTime >= 0 ? "timer.circle.fill" : "checkmark.circle.fill")
|
|
321
|
+
.resizable()
|
|
322
|
+
.scaledToFit()
|
|
323
|
+
.frame(width: 20, height: 20)
|
|
324
|
+
.foregroundColor(context.state.deliveryTime >= 0 ? .green : .blue)
|
|
325
|
+
} minimal: {
|
|
326
|
+
Text(context.state.message).font(.system(size: 12))
|
|
327
|
+
}
|
|
328
|
+
.widgetURL(URL(string: "http://www.apple.com"))
|
|
329
|
+
.keylineTint(Color.red)
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
private let formatter: NumberFormatter = {
|
|
334
|
+
let formatter = NumberFormatter()
|
|
335
|
+
formatter.maximumFractionDigits = 0
|
|
336
|
+
formatter.minimumFractionDigits = 0
|
|
337
|
+
return formatter
|
|
338
|
+
}()
|
|
378
339
|
}
|
|
379
340
|
|
|
380
|
-
struct
|
|
381
|
-
|
|
341
|
+
struct LockScreenView: View {
|
|
342
|
+
@State private var message = ""
|
|
343
|
+
@State private var deliveryTime: Double = 0
|
|
344
|
+
// for console debugging
|
|
345
|
+
let logger = Logger(subsystem: "${bundleId}.${name}", category: "Widget")
|
|
382
346
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
347
|
+
var body: some View {
|
|
348
|
+
ZStack {
|
|
349
|
+
LinearGradient(
|
|
350
|
+
gradient: Gradient(colors: [Color.gray.opacity(0.3), Color.black]),
|
|
351
|
+
startPoint: .top,
|
|
352
|
+
endPoint: .bottom
|
|
353
|
+
)
|
|
354
|
+
VStack {
|
|
355
|
+
Spacer()
|
|
356
|
+
Image(systemName: deliveryTime >= 0 ? "car.side.arrowtriangle.up.fill" : "face.smiling.inverse")
|
|
357
|
+
.resizable()
|
|
358
|
+
.scaledToFit()
|
|
359
|
+
.frame(width: 50, height: 50)
|
|
360
|
+
.foregroundColor(deliveryTime >= 0 ? .green : .blue)
|
|
361
|
+
Spacer()
|
|
362
|
+
Text("\\(message)")
|
|
363
|
+
.foregroundStyle(.white)
|
|
364
|
+
Spacer()
|
|
365
|
+
}
|
|
366
|
+
}.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
init(message: String = "", deliveryTime: Double = 0) {
|
|
370
|
+
_message = State(initialValue: message)
|
|
371
|
+
_deliveryTime = State(initialValue: deliveryTime)
|
|
372
|
+
|
|
373
|
+
// Logs the deliveryTime at init for debugging purposes if needed
|
|
374
|
+
logger.log("deliveryTime: \\(deliveryTime)")
|
|
375
|
+
}
|
|
392
376
|
}${os_1.EOL}`;
|
|
393
377
|
fs.writeFileSync(widgetLiveActivityPath, content);
|
|
394
378
|
}
|
|
@@ -396,129 +380,179 @@ struct ContentView: View {
|
|
|
396
380
|
content = `import SwiftUI
|
|
397
381
|
import WidgetKit
|
|
398
382
|
|
|
399
|
-
|
|
383
|
+
/**
|
|
384
|
+
* Widget data shared between the app and the widget extension.
|
|
385
|
+
*/
|
|
386
|
+
struct WidgetData: Codable {
|
|
387
|
+
let pizzas: [String]
|
|
388
|
+
let orderTime: Double
|
|
389
|
+
let delivered: Bool
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
struct Provider: TimelineProvider {
|
|
393
|
+
|
|
400
394
|
func placeholder(in context: Context) -> SimpleEntry {
|
|
401
|
-
SimpleEntry(date: Date(),
|
|
395
|
+
SimpleEntry(date: Date(), pizza: "Pepperoni", delivered: false, orderTime: Date())
|
|
402
396
|
}
|
|
403
|
-
|
|
404
|
-
func
|
|
405
|
-
|
|
406
|
-
|
|
397
|
+
|
|
398
|
+
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
|
|
399
|
+
let entry = SimpleEntry(date: Date(), pizza: "Pepperoni", delivered: false, orderTime: Date())
|
|
400
|
+
completion(entry)
|
|
407
401
|
}
|
|
408
|
-
|
|
409
|
-
func
|
|
410
|
-
SimpleEntry
|
|
411
|
-
> {
|
|
402
|
+
|
|
403
|
+
func getTimeline(in context: Context, completion: @escaping @Sendable (Timeline<Entry>) -> ()) {
|
|
412
404
|
var entries: [SimpleEntry] = []
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
405
|
+
|
|
406
|
+
if let sharedDefaults = UserDefaults(suiteName: "group.${bundleId}") {
|
|
407
|
+
let currentDate = Date()
|
|
408
|
+
if let jsonString = sharedDefaults.string(forKey: "widgetData") {
|
|
409
|
+
if let jsonData = jsonString.data(using: .utf8) {
|
|
410
|
+
do {
|
|
411
|
+
let widgetData = try JSONDecoder().decode(WidgetData.self, from: jsonData)
|
|
412
|
+
let pizzas = widgetData.pizzas
|
|
413
|
+
let orderTime = Date(timeIntervalSince1970: widgetData.orderTime/1000)
|
|
414
|
+
let delivered = widgetData.delivered
|
|
415
|
+
|
|
416
|
+
// Generate a timeline of entries 1 second apart, starting from the current date.
|
|
417
|
+
for secondOffset in 0..<pizzas.count {
|
|
418
|
+
let entryDate = Calendar.current.date(
|
|
419
|
+
byAdding: .second, value: secondOffset, to: currentDate)!
|
|
420
|
+
let entry = SimpleEntry(date: entryDate, pizza: secondOffset < pizzas.count ? pizzas[secondOffset] : pizzas[0], delivered: delivered, orderTime: orderTime)
|
|
421
|
+
entries.append(entry)
|
|
422
|
+
}
|
|
423
|
+
} catch {
|
|
424
|
+
print("Failed to decode JSON: (error)")
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
} else {
|
|
428
|
+
let entry = SimpleEntry(date: currentDate, pizza: "", delivered: false, orderTime: nil)
|
|
429
|
+
entries.append(entry)
|
|
431
430
|
}
|
|
432
|
-
let entry = SimpleEntry(date: entryDate, random: config.random, configuration: config)
|
|
433
|
-
entries.append(entry)
|
|
434
431
|
}
|
|
435
|
-
|
|
436
|
-
|
|
432
|
+
|
|
433
|
+
let timeline = Timeline(entries: entries, policy: .atEnd)
|
|
434
|
+
completion(timeline)
|
|
437
435
|
}
|
|
436
|
+
|
|
437
|
+
// func relevances() async -> WidgetRelevances<Void> {
|
|
438
|
+
// // Generate a list containing the contexts this widget is relevant in.
|
|
439
|
+
// }
|
|
438
440
|
}
|
|
439
441
|
|
|
440
442
|
struct SimpleEntry: TimelineEntry {
|
|
441
443
|
let date: Date
|
|
442
|
-
let
|
|
443
|
-
let
|
|
444
|
+
let pizza: String
|
|
445
|
+
let delivered: Bool
|
|
446
|
+
let orderTime: Date?
|
|
444
447
|
}
|
|
445
448
|
|
|
446
449
|
struct WidgetView: View {
|
|
450
|
+
@Environment(\\.widgetFamily) var widgetFamily
|
|
447
451
|
var entry: Provider.Entry
|
|
448
452
|
|
|
449
453
|
var body: some View {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
.
|
|
456
|
-
|
|
457
|
-
.
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
454
|
+
VStack {
|
|
455
|
+
if (entry.pizza != "") {
|
|
456
|
+
Spacer()
|
|
457
|
+
Image(systemName: entry.delivered ? "face.smiling.inverse" : "car.side")
|
|
458
|
+
.resizable()
|
|
459
|
+
.scaledToFit()
|
|
460
|
+
.frame(width: iconSize(for: widgetFamily), height: iconSize(for: widgetFamily))
|
|
461
|
+
.foregroundColor(entry.delivered ? .blue : .green)
|
|
462
|
+
Spacer()
|
|
463
|
+
if (entry.delivered) {
|
|
464
|
+
Text("Pizza Delivered!")
|
|
465
|
+
.font(.system(size: fontSize(for: widgetFamily), weight: .bold))
|
|
466
|
+
.foregroundStyle(.white)
|
|
467
|
+
} else {
|
|
468
|
+
HStack(spacing: 4) {
|
|
469
|
+
Text("Ordered:")
|
|
470
|
+
.font(.system(size: fontSize(for: widgetFamily)))
|
|
471
|
+
.foregroundStyle(.white)
|
|
472
|
+
Text(entry.orderTime!, style: .time)
|
|
473
|
+
.font(.system(size: fontSize(for: widgetFamily), weight: .bold))
|
|
474
|
+
.foregroundStyle(.white)
|
|
475
|
+
}
|
|
476
|
+
HStack(spacing: 4) {
|
|
477
|
+
Text("Pizza:")
|
|
478
|
+
.font(.system(size: fontSize(for: widgetFamily)))
|
|
479
|
+
.foregroundStyle(.white)
|
|
480
|
+
Text(entry.pizza)
|
|
481
|
+
.font(.system(size: fontSize(for: widgetFamily), weight: .bold))
|
|
482
|
+
.foregroundStyle(.white)
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
Spacer()
|
|
486
|
+
} else {
|
|
487
|
+
Spacer()
|
|
488
|
+
Image(systemName: "car.side.rear.open")
|
|
489
|
+
.resizable()
|
|
490
|
+
.scaledToFit()
|
|
491
|
+
.frame(width: iconSize(for: widgetFamily), height: iconSize(for: widgetFamily))
|
|
492
|
+
.foregroundColor(.gray)
|
|
493
|
+
Spacer()
|
|
494
|
+
Text("Awaiting orders...")
|
|
465
495
|
.foregroundStyle(.white)
|
|
496
|
+
Spacer()
|
|
466
497
|
}
|
|
467
498
|
}.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
468
499
|
}
|
|
500
|
+
|
|
501
|
+
private func iconSize(for family: WidgetFamily) -> CGFloat {
|
|
502
|
+
switch family {
|
|
503
|
+
case .systemSmall:
|
|
504
|
+
return 65
|
|
505
|
+
case .systemMedium:
|
|
506
|
+
return 85
|
|
507
|
+
case .systemLarge:
|
|
508
|
+
return 150
|
|
509
|
+
default:
|
|
510
|
+
return 65
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
private func fontSize(for family: WidgetFamily) -> CGFloat {
|
|
515
|
+
switch family {
|
|
516
|
+
case .systemSmall:
|
|
517
|
+
return 12
|
|
518
|
+
case .systemMedium:
|
|
519
|
+
return 14
|
|
520
|
+
case .systemLarge:
|
|
521
|
+
return 18
|
|
522
|
+
default:
|
|
523
|
+
return 14
|
|
524
|
+
}
|
|
525
|
+
}
|
|
469
526
|
}
|
|
470
527
|
|
|
471
528
|
@available(iOSApplicationExtension 17.0, *)
|
|
472
529
|
struct ${capitalName}HomeScreenWidget: Widget {
|
|
473
530
|
let kind: String = "widget"
|
|
474
|
-
|
|
531
|
+
|
|
475
532
|
var body: some WidgetConfiguration {
|
|
476
|
-
|
|
477
|
-
entry in
|
|
533
|
+
StaticConfiguration(kind: kind, provider: Provider()) { entry in
|
|
478
534
|
WidgetView(entry: entry)
|
|
479
|
-
.containerBackground(
|
|
535
|
+
.containerBackground(for: .widget) {
|
|
536
|
+
LinearGradient(
|
|
537
|
+
gradient: Gradient(colors: [Color.black.opacity(0.6), Color.black]),
|
|
538
|
+
startPoint: .top,
|
|
539
|
+
endPoint: .bottom
|
|
540
|
+
)
|
|
541
|
+
}
|
|
480
542
|
}
|
|
481
|
-
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
extension ConfigurationAppIntent {
|
|
485
|
-
fileprivate static var pepperoni: ConfigurationAppIntent {
|
|
486
|
-
let intent = ConfigurationAppIntent()
|
|
487
|
-
intent.favoritePizza = "Pepperoni"
|
|
488
|
-
intent.random = "Georgia"
|
|
489
|
-
return intent
|
|
490
|
-
}
|
|
491
|
-
fileprivate static var supreme: ConfigurationAppIntent {
|
|
492
|
-
let intent = ConfigurationAppIntent()
|
|
493
|
-
intent.favoritePizza = "Supreme"
|
|
494
|
-
intent.random = "Kansas City"
|
|
495
|
-
return intent
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
fileprivate static var cowboy: ConfigurationAppIntent {
|
|
499
|
-
let intent = ConfigurationAppIntent()
|
|
500
|
-
intent.favoritePizza = "Cowboy"
|
|
501
|
-
intent.random = "Nashville"
|
|
502
|
-
return intent
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
fileprivate static var pineswine: ConfigurationAppIntent {
|
|
506
|
-
let intent = ConfigurationAppIntent()
|
|
507
|
-
intent.favoritePizza = "Pine & Swine"
|
|
508
|
-
intent.random = "Portland"
|
|
509
|
-
return intent
|
|
543
|
+
.configurationDisplayName("${capitalName} Widget")
|
|
544
|
+
.description("${capitalName} delivery service.")
|
|
510
545
|
}
|
|
511
546
|
}
|
|
512
547
|
|
|
513
548
|
#Preview(as: .systemSmall) {
|
|
514
549
|
${capitalName}HomeScreenWidget()
|
|
515
550
|
} timeline: {
|
|
516
|
-
SimpleEntry(date: .now,
|
|
517
|
-
SimpleEntry(date: .now,
|
|
551
|
+
SimpleEntry(date: .now, pizza: "Pepperoni", delivered: false, orderTime: Date())
|
|
552
|
+
SimpleEntry(date: .now, pizza: "Hawaiian", delivered: false, orderTime: Date())
|
|
518
553
|
}${os_1.EOL}`;
|
|
519
554
|
fs.writeFileSync(widgetHomeScreenPath, content);
|
|
520
555
|
}
|
|
521
|
-
const bundleId = this.$projectConfigService.getValue(`id`, "");
|
|
522
556
|
content = `{
|
|
523
557
|
"${bundleId}.${name}": "{set-your-provision-profile-id}"
|
|
524
558
|
}`;
|
|
@@ -624,18 +658,22 @@ extension ConfigurationAppIntent {
|
|
|
624
658
|
}${os_1.EOL}`;
|
|
625
659
|
fs.writeFileSync(extensionsConfigPath, content);
|
|
626
660
|
console.log(`🚀 Your widget is now ready to develop: App_Resources/iOS/extensions/${name}.\n`);
|
|
627
|
-
|
|
628
|
-
-
|
|
629
|
-
-
|
|
630
|
-
|
|
631
|
-
|
|
661
|
+
const steps = ["Followup steps:"];
|
|
662
|
+
steps.push("- Check App_Resources/iOS/build.xcconfig uses IPHONEOS_DEPLOYMENT_TARGET = 17 or higher.");
|
|
663
|
+
steps.push("- Update App_Resources/iOS/extensions/provisioning.json with your profile id.");
|
|
664
|
+
if ([0, 1].includes(type)) {
|
|
665
|
+
steps.push(`- Customize App_Resources/iOS/extensions/${name}/${(0, utils_1.capitalizeFirstLetter)(name)}LiveActivity.swift for your display.`);
|
|
666
|
+
steps.push(`- Customize Shared_Resources/iOS/SharedWidget/Sources/SharedWidget/${(0, utils_1.capitalizeFirstLetter)(name)}Model.swift for your data.`);
|
|
667
|
+
}
|
|
668
|
+
console.log(steps.join("\n"));
|
|
632
669
|
}
|
|
633
670
|
// if (fs.existsSync(filePath)) {
|
|
634
671
|
// this.$errors.failWithHelp(`Error: File '${filePath}' already exists.`);
|
|
635
672
|
// return;
|
|
636
673
|
// }
|
|
637
674
|
}
|
|
638
|
-
generateAppleUtility(projectDir, name) {
|
|
675
|
+
generateAppleUtility(projectDir, name, bundleId, type) {
|
|
676
|
+
const capitalName = (0, utils_1.capitalizeFirstLetter)(name);
|
|
639
677
|
const appResourcePath = this.$projectData.appResourcesDirectoryPath;
|
|
640
678
|
const appResourceSrcPath = path.join(appResourcePath, "iOS", "src");
|
|
641
679
|
const appleUtilityPath = path.join(appResourceSrcPath, `AppleWidgetUtils.swift`);
|
|
@@ -645,30 +683,21 @@ extension ConfigurationAppIntent {
|
|
|
645
683
|
}
|
|
646
684
|
if (!fs.existsSync(appleUtilityPath)) {
|
|
647
685
|
}
|
|
648
|
-
|
|
649
|
-
import UIKit
|
|
650
|
-
import ActivityKit
|
|
651
|
-
import WidgetKit
|
|
652
|
-
import SharedWidget
|
|
653
|
-
|
|
654
|
-
@objcMembers
|
|
655
|
-
public class AppleWidgetUtils: NSObject {
|
|
656
|
-
|
|
657
|
-
// Live Activity Handling
|
|
686
|
+
const liveActivityUtilities = `// Live Activity Handling
|
|
658
687
|
public static func startActivity(_ data: NSDictionary) {
|
|
659
688
|
if ActivityAuthorizationInfo().areActivitiesEnabled {
|
|
660
689
|
let numberOfPizzas = data.object(forKey: "numberOfPizzas") as! Int
|
|
661
690
|
let totalAmount = data.object(forKey: "totalAmount") as! String
|
|
662
|
-
let attrs = ${
|
|
691
|
+
let attrs = ${capitalName}Model(numberOfPizzas: numberOfPizzas, totalAmount: totalAmount)
|
|
663
692
|
|
|
664
|
-
let
|
|
665
|
-
let deliveryTime = data.object(forKey: "deliveryTime") as!
|
|
666
|
-
let initialStatus = ${
|
|
667
|
-
|
|
693
|
+
let message = data.object(forKey: "message") as! String
|
|
694
|
+
let deliveryTime = data.object(forKey: "deliveryTime") as! Double
|
|
695
|
+
let initialStatus = ${capitalName}Model.DeliveryStatus(
|
|
696
|
+
message: message, deliveryTime: deliveryTime)
|
|
668
697
|
let content = ActivityContent(state: initialStatus, staleDate: nil)
|
|
669
698
|
|
|
670
699
|
do {
|
|
671
|
-
let activity = try Activity<${
|
|
700
|
+
let activity = try Activity<${capitalName}Model>.request(
|
|
672
701
|
attributes: attrs,
|
|
673
702
|
content: content,
|
|
674
703
|
pushType: nil)
|
|
@@ -681,13 +710,13 @@ public class AppleWidgetUtils: NSObject {
|
|
|
681
710
|
public static func updateActivity(_ data: NSDictionary) {
|
|
682
711
|
if ActivityAuthorizationInfo().areActivitiesEnabled {
|
|
683
712
|
Task {
|
|
684
|
-
let
|
|
685
|
-
let deliveryTime = data.object(forKey: "deliveryTime") as!
|
|
686
|
-
let status = ${
|
|
687
|
-
|
|
713
|
+
let message = data.object(forKey: "message") as! String
|
|
714
|
+
let deliveryTime = data.object(forKey: "deliveryTime") as! Double
|
|
715
|
+
let status = ${capitalName}Model.DeliveryStatus(
|
|
716
|
+
message: message, deliveryTime: deliveryTime)
|
|
688
717
|
let content = ActivityContent(state: status, staleDate: nil)
|
|
689
718
|
|
|
690
|
-
for activity in Activity<${
|
|
719
|
+
for activity in Activity<${capitalName}Model>.activities {
|
|
691
720
|
await activity.update(content)
|
|
692
721
|
}
|
|
693
722
|
}
|
|
@@ -696,27 +725,47 @@ public class AppleWidgetUtils: NSObject {
|
|
|
696
725
|
public static func cancelActivity(_ data: NSDictionary) {
|
|
697
726
|
if ActivityAuthorizationInfo().areActivitiesEnabled {
|
|
698
727
|
Task {
|
|
699
|
-
let
|
|
700
|
-
let status = ${
|
|
701
|
-
|
|
728
|
+
let message = data.object(forKey: "message") as! String
|
|
729
|
+
let status = ${capitalName}Model.DeliveryStatus(
|
|
730
|
+
message: message, deliveryTime: 0)
|
|
702
731
|
let content = ActivityContent(state: status, staleDate: nil)
|
|
703
732
|
|
|
704
|
-
for activity in Activity<${
|
|
733
|
+
for activity in Activity<${capitalName}Model>.activities {
|
|
705
734
|
await activity.end(content, dismissalPolicy: .immediate)
|
|
706
735
|
}
|
|
707
736
|
}
|
|
708
737
|
}
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
738
|
+
}`;
|
|
739
|
+
let content = `import Foundation
|
|
740
|
+
import UIKit
|
|
741
|
+
import ActivityKit
|
|
742
|
+
import WidgetKit
|
|
743
|
+
${[0, 1].includes(type) ? "import SharedWidget" : ""}
|
|
744
|
+
|
|
745
|
+
@objcMembers
|
|
746
|
+
public class AppleWidgetUtils: NSObject {
|
|
747
|
+
${[0, 1].includes(type) ? liveActivityUtilities : ""}
|
|
748
|
+
// Shared App Group Data
|
|
749
|
+
public static func getData(key: String) -> String? {
|
|
750
|
+
guard let sharedDefaults = UserDefaults(suiteName: "group.${bundleId}") else {
|
|
751
|
+
return nil
|
|
752
|
+
}
|
|
753
|
+
return sharedDefaults.object(forKey: key) as? String
|
|
754
|
+
}
|
|
755
|
+
public static func updateData(key: String, _ data: String) {
|
|
756
|
+
guard let sharedDefaults = UserDefaults(suiteName: "group.${bundleId}") else {
|
|
757
|
+
return
|
|
758
|
+
}
|
|
759
|
+
sharedDefaults.set(data, forKey: key)
|
|
760
|
+
sharedDefaults.synchronize()
|
|
761
|
+
}
|
|
762
|
+
public static func removeData(key: String) {
|
|
763
|
+
guard let sharedDefaults = UserDefaults(suiteName: "group.${bundleId}") else {
|
|
764
|
+
return
|
|
765
|
+
}
|
|
766
|
+
sharedDefaults.removeObject(forKey: key)
|
|
767
|
+
sharedDefaults.synchronize()
|
|
768
|
+
}
|
|
720
769
|
// Home Screen Widget Handling
|
|
721
770
|
public static func updateWidget() {
|
|
722
771
|
if #available(iOS 14.0, *) {
|
|
@@ -733,17 +782,19 @@ public class AppleWidgetUtils: NSObject {
|
|
|
733
782
|
declare interface AppleWidgetModelData {
|
|
734
783
|
numberOfPizzas: number;
|
|
735
784
|
totalAmount: string;
|
|
736
|
-
|
|
785
|
+
message: string;
|
|
737
786
|
deliveryTime: number;
|
|
738
787
|
}
|
|
739
788
|
declare class AppleWidgetUtils extends NSObject {
|
|
740
789
|
static startActivity(data: AppleWidgetModelData): void;
|
|
741
790
|
static updateActivity(
|
|
742
|
-
data: Pick<AppleWidgetModelData, "
|
|
791
|
+
data: Pick<AppleWidgetModelData, "message" | "deliveryTime">
|
|
743
792
|
): void;
|
|
744
|
-
static cancelActivity(data: Pick<AppleWidgetModelData, "
|
|
745
|
-
static showAllActivities(): void;
|
|
793
|
+
static cancelActivity(data: Pick<AppleWidgetModelData, "message">): void;
|
|
746
794
|
static updateWidget(): void;
|
|
795
|
+
static updateDataWithKey(key: string, data: string): void;
|
|
796
|
+
static getDataWithKey(key: string): string;
|
|
797
|
+
static removeDataWithKey(key: string): void;
|
|
747
798
|
}${os_1.EOL}`;
|
|
748
799
|
if (!fs.existsSync(referenceTypesPath)) {
|
|
749
800
|
const references = `/// <reference path="./node_modules/@nativescript/types-android/index.d.ts" />
|