mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-15 20:10:30 +00:00
Remove widget extension, keep the keep-alive banner in-app only
Drops the StikDebugWidgets extension target, the shared ActivityAttributes, and the KeepAliveLiveActivity controller — no Dynamic Island / Lock Screen presentation. The banner stays as the existing in-app overlay in HomeView, now also shown when holding an app from the "Other" tab. project.pbxproj, Info.plist, and AppBootstrapper.swift are back to their pre-widget state. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EpCxAimrBo9RA8v6BxSEXT
This commit is contained in:
parent
23e8052c7b
commit
e4f02100ee
9 changed files with 1 additions and 428 deletions
|
|
@ -9,7 +9,6 @@
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
68D569BE2E1B415700A5BA36 /* CodeEditorView in Frameworks */ = {isa = PBXBuildFile; productRef = 68D569BD2E1B415700A5BA36 /* CodeEditorView */; };
|
68D569BE2E1B415700A5BA36 /* CodeEditorView in Frameworks */ = {isa = PBXBuildFile; productRef = 68D569BD2E1B415700A5BA36 /* CodeEditorView */; };
|
||||||
68D569C02E1B415700A5BA36 /* LanguageSupport in Frameworks */ = {isa = PBXBuildFile; productRef = 68D569BF2E1B415700A5BA36 /* LanguageSupport */; };
|
68D569C02E1B415700A5BA36 /* LanguageSupport in Frameworks */ = {isa = PBXBuildFile; productRef = 68D569BF2E1B415700A5BA36 /* LanguageSupport */; };
|
||||||
F00DCAFE000000000000E00B /* StikDebugWidgets.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F00DCAFE000000000000E002 /* StikDebugWidgets.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
|
@ -27,13 +26,6 @@
|
||||||
remoteGlobalIDString = DC6F1D362D94EADD0071B2B6;
|
remoteGlobalIDString = DC6F1D362D94EADD0071B2B6;
|
||||||
remoteInfo = StikDebug;
|
remoteInfo = StikDebug;
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E00D /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = DC6F1D2F2D94EADD0071B2B6 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = F00DCAFE000000000000E001;
|
|
||||||
remoteInfo = StikDebugWidgets;
|
|
||||||
};
|
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
|
@ -43,7 +35,6 @@
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 13;
|
dstSubfolderSpec = 13;
|
||||||
files = (
|
files = (
|
||||||
F00DCAFE000000000000E00B /* StikDebugWidgets.appex in Embed Foundation Extensions */,
|
|
||||||
);
|
);
|
||||||
name = "Embed Foundation Extensions";
|
name = "Embed Foundation Extensions";
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
@ -56,7 +47,6 @@
|
||||||
DC6F1D372D94EADD0071B2B6 /* StikDebug.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StikDebug.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
DC6F1D372D94EADD0071B2B6 /* StikDebug.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StikDebug.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
DC6F1D482D94EADF0071B2B6 /* StikDebugTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StikDebugTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
DC6F1D482D94EADF0071B2B6 /* StikDebugTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StikDebugTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
DC6F1D522D94EADF0071B2B6 /* StikDebugUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StikDebugUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
DC6F1D522D94EADF0071B2B6 /* StikDebugUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StikDebugUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
F00DCAFE000000000000E002 /* StikDebugWidgets.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = StikDebugWidgets.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||||
|
|
@ -67,13 +57,6 @@
|
||||||
);
|
);
|
||||||
target = DC6F1D362D94EADD0071B2B6 /* StikDebug */;
|
target = DC6F1D362D94EADD0071B2B6 /* StikDebug */;
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E00E /* Exceptions for "StikDebugWidgets" folder in "StikDebugWidgets" target */ = {
|
|
||||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
|
||||||
membershipExceptions = (
|
|
||||||
Info.plist,
|
|
||||||
);
|
|
||||||
target = F00DCAFE000000000000E001 /* StikDebugWidgets */;
|
|
||||||
};
|
|
||||||
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
|
@ -85,19 +68,6 @@
|
||||||
path = StikDebug;
|
path = StikDebug;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E006 /* StikDebugWidgets */ = {
|
|
||||||
isa = PBXFileSystemSynchronizedRootGroup;
|
|
||||||
exceptions = (
|
|
||||||
F00DCAFE000000000000E00E /* Exceptions for "StikDebugWidgets" folder in "StikDebugWidgets" target */,
|
|
||||||
);
|
|
||||||
path = StikDebugWidgets;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
F00DCAFE000000000000E007 /* StikDebugShared */ = {
|
|
||||||
isa = PBXFileSystemSynchronizedRootGroup;
|
|
||||||
path = StikDebugShared;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
DC6F1D4B2D94EADF0071B2B6 /* StikDebugTests */ = {
|
DC6F1D4B2D94EADF0071B2B6 /* StikDebugTests */ = {
|
||||||
isa = PBXFileSystemSynchronizedRootGroup;
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
path = StikDebugTests;
|
path = StikDebugTests;
|
||||||
|
|
@ -134,13 +104,6 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E004 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
|
@ -148,8 +111,6 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
DC6F1D392D94EADD0071B2B6 /* StikDebug */,
|
DC6F1D392D94EADD0071B2B6 /* StikDebug */,
|
||||||
F00DCAFE000000000000E007 /* StikDebugShared */,
|
|
||||||
F00DCAFE000000000000E006 /* StikDebugWidgets */,
|
|
||||||
DC6F1D4B2D94EADF0071B2B6 /* StikDebugTests */,
|
DC6F1D4B2D94EADF0071B2B6 /* StikDebugTests */,
|
||||||
DC6F1D552D94EADF0071B2B6 /* StikDebugUITests */,
|
DC6F1D552D94EADF0071B2B6 /* StikDebugUITests */,
|
||||||
DC6F1D752D94EB620071B2B6 /* Frameworks */,
|
DC6F1D752D94EB620071B2B6 /* Frameworks */,
|
||||||
|
|
@ -163,7 +124,6 @@
|
||||||
DC6F1D372D94EADD0071B2B6 /* StikDebug.app */,
|
DC6F1D372D94EADD0071B2B6 /* StikDebug.app */,
|
||||||
DC6F1D482D94EADF0071B2B6 /* StikDebugTests.xctest */,
|
DC6F1D482D94EADF0071B2B6 /* StikDebugTests.xctest */,
|
||||||
DC6F1D522D94EADF0071B2B6 /* StikDebugUITests.xctest */,
|
DC6F1D522D94EADF0071B2B6 /* StikDebugUITests.xctest */,
|
||||||
F00DCAFE000000000000E002 /* StikDebugWidgets.appex */,
|
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -192,11 +152,9 @@
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
F00DCAFE000000000000E00C /* PBXTargetDependency */,
|
|
||||||
);
|
);
|
||||||
fileSystemSynchronizedGroups = (
|
fileSystemSynchronizedGroups = (
|
||||||
DC6F1D392D94EADD0071B2B6 /* StikDebug */,
|
DC6F1D392D94EADD0071B2B6 /* StikDebug */,
|
||||||
F00DCAFE000000000000E007 /* StikDebugShared */,
|
|
||||||
);
|
);
|
||||||
name = StikDebug;
|
name = StikDebug;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
|
|
@ -207,29 +165,6 @@
|
||||||
productReference = DC6F1D372D94EADD0071B2B6 /* StikDebug.app */;
|
productReference = DC6F1D372D94EADD0071B2B6 /* StikDebug.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E001 /* StikDebugWidgets */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = F00DCAFE000000000000E008 /* Build configuration list for PBXNativeTarget "StikDebugWidgets" */;
|
|
||||||
buildPhases = (
|
|
||||||
F00DCAFE000000000000E003 /* Sources */,
|
|
||||||
F00DCAFE000000000000E004 /* Frameworks */,
|
|
||||||
F00DCAFE000000000000E005 /* Resources */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
);
|
|
||||||
fileSystemSynchronizedGroups = (
|
|
||||||
F00DCAFE000000000000E006 /* StikDebugWidgets */,
|
|
||||||
F00DCAFE000000000000E007 /* StikDebugShared */,
|
|
||||||
);
|
|
||||||
name = StikDebugWidgets;
|
|
||||||
packageProductDependencies = (
|
|
||||||
);
|
|
||||||
productName = StikDebugWidgets;
|
|
||||||
productReference = F00DCAFE000000000000E002 /* StikDebugWidgets.appex */;
|
|
||||||
productType = "com.apple.product-type.app-extension";
|
|
||||||
};
|
|
||||||
DC6F1D472D94EADF0071B2B6 /* StikDebugTests */ = {
|
DC6F1D472D94EADF0071B2B6 /* StikDebugTests */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = DC6F1D5F2D94EADF0071B2B6 /* Build configuration list for PBXNativeTarget "StikDebugTests" */;
|
buildConfigurationList = DC6F1D5F2D94EADF0071B2B6 /* Build configuration list for PBXNativeTarget "StikDebugTests" */;
|
||||||
|
|
@ -298,9 +233,6 @@
|
||||||
CreatedOnToolsVersion = 16.2;
|
CreatedOnToolsVersion = 16.2;
|
||||||
TestTargetID = DC6F1D362D94EADD0071B2B6;
|
TestTargetID = DC6F1D362D94EADD0071B2B6;
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E001 = {
|
|
||||||
CreatedOnToolsVersion = 16.2;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = DC6F1D322D94EADD0071B2B6 /* Build configuration list for PBXProject "StikDebug" */;
|
buildConfigurationList = DC6F1D322D94EADD0071B2B6 /* Build configuration list for PBXProject "StikDebug" */;
|
||||||
|
|
@ -323,7 +255,6 @@
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
DC6F1D362D94EADD0071B2B6 /* StikDebug */,
|
DC6F1D362D94EADD0071B2B6 /* StikDebug */,
|
||||||
F00DCAFE000000000000E001 /* StikDebugWidgets */,
|
|
||||||
DC6F1D472D94EADF0071B2B6 /* StikDebugTests */,
|
DC6F1D472D94EADF0071B2B6 /* StikDebugTests */,
|
||||||
DC6F1D512D94EADF0071B2B6 /* StikDebugUITests */,
|
DC6F1D512D94EADF0071B2B6 /* StikDebugUITests */,
|
||||||
);
|
);
|
||||||
|
|
@ -352,13 +283,6 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E005 /* Resources */ = {
|
|
||||||
isa = PBXResourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
|
@ -383,13 +307,6 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E003 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
|
|
@ -403,11 +320,6 @@
|
||||||
target = DC6F1D362D94EADD0071B2B6 /* StikDebug */;
|
target = DC6F1D362D94EADD0071B2B6 /* StikDebug */;
|
||||||
targetProxy = DC6F1D532D94EADF0071B2B6 /* PBXContainerItemProxy */;
|
targetProxy = DC6F1D532D94EADF0071B2B6 /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E00C /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = F00DCAFE000000000000E001 /* StikDebugWidgets */;
|
|
||||||
targetProxy = F00DCAFE000000000000E00D /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
/* End PBXTargetDependency section */
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
|
|
@ -756,64 +668,6 @@
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E009 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEVELOPMENT_TEAM = "";
|
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
|
||||||
INFOPLIST_FILE = StikDebugWidgets/Info.plist;
|
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = StikDebug;
|
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/Frameworks",
|
|
||||||
"@executable_path/../../Frameworks",
|
|
||||||
);
|
|
||||||
MARKETING_VERSION = 3.1.6;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.stik.stikdebug.widgets;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SDKROOT = auto;
|
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
F00DCAFE000000000000E00A /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEVELOPMENT_TEAM = "";
|
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
|
||||||
INFOPLIST_FILE = StikDebugWidgets/Info.plist;
|
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = StikDebug;
|
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/Frameworks",
|
|
||||||
"@executable_path/../../Frameworks",
|
|
||||||
);
|
|
||||||
MARKETING_VERSION = 3.1.6;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.stik.stikdebug.widgets;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SDKROOT = auto;
|
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
|
|
@ -853,15 +707,6 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
F00DCAFE000000000000E008 /* Build configuration list for PBXNativeTarget "StikDebugWidgets" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
F00DCAFE000000000000E009 /* Debug */,
|
|
||||||
F00DCAFE000000000000E00A /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCRemoteSwiftPackageReference section */
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,6 @@ enum AppBootstrapper {
|
||||||
startConfiguredKeepAliveServices()
|
startConfiguredKeepAliveServices()
|
||||||
applyDocumentPickerCopyWorkaround()
|
applyDocumentPickerCopyWorkaround()
|
||||||
NetworkPathMonitor.shared.start()
|
NetworkPathMonitor.shared.start()
|
||||||
// No hold is active at launch, so clear any Live Activity a previous
|
|
||||||
// (possibly force-quit) run left showing in the Dynamic Island.
|
|
||||||
KeepAliveLiveActivity.endStaleActivities()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func registerDefaultSettings() {
|
private static func registerDefaultSettings() {
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,6 @@
|
||||||
<string>_stikdebug._tcp</string>
|
<string>_stikdebug._tcp</string>
|
||||||
<string>_stikdebug._udp</string>
|
<string>_stikdebug._udp</string>
|
||||||
</array>
|
</array>
|
||||||
<key>NSSupportsLiveActivities</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSSupportsLiveActivitiesFrequentUpdates</key>
|
|
||||||
<true/>
|
|
||||||
<key>UIBackgroundModes</key>
|
<key>UIBackgroundModes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>audio</string>
|
<string>audio</string>
|
||||||
|
|
|
||||||
|
|
@ -72,12 +72,7 @@ final class BackgroundAliveManager: ObservableObject {
|
||||||
lock.unlock()
|
lock.unlock()
|
||||||
|
|
||||||
let name = displayName ?? bundleID
|
let name = displayName ?? bundleID
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async { self.activeAppName = name }
|
||||||
self.activeAppName = name
|
|
||||||
// Surface the hold in the Dynamic Island / Lock Screen so it stays
|
|
||||||
// visible while the user is in the held app.
|
|
||||||
KeepAliveLiveActivity.start(appName: name, bundleID: bundleID)
|
|
||||||
}
|
|
||||||
LogManager.shared.addInfoLog("Starting background keep-alive for \(name)")
|
LogManager.shared.addInfoLog("Starting background keep-alive for \(name)")
|
||||||
|
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
DispatchQueue.global(qos: .userInitiated).async {
|
||||||
|
|
@ -106,7 +101,6 @@ final class BackgroundAliveManager: ObservableObject {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
if stillCurrent {
|
if stillCurrent {
|
||||||
self.activeAppName = nil
|
self.activeAppName = nil
|
||||||
KeepAliveLiveActivity.end()
|
|
||||||
}
|
}
|
||||||
if !succeeded {
|
if !succeeded {
|
||||||
showAlert(
|
showAlert(
|
||||||
|
|
|
||||||
|
|
@ -1,114 +0,0 @@
|
||||||
//
|
|
||||||
// KeepAliveLiveActivity.swift
|
|
||||||
// StikDebug
|
|
||||||
//
|
|
||||||
// App-side controller for the background keep-alive Live Activity. Starts a
|
|
||||||
// Live Activity when a hold begins so it shows in the Dynamic Island (on
|
|
||||||
// compatible iPhones) and on the Lock Screen, and ends it when the hold stops.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
#if canImport(ActivityKit)
|
|
||||||
import ActivityKit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum KeepAliveLiveActivity {
|
|
||||||
private static let lock = NSLock()
|
|
||||||
/// Type-erased storage for the current `Activity`, so this enum has no
|
|
||||||
/// availability requirement of its own and callers don't need to guard.
|
|
||||||
private static var storage: Any?
|
|
||||||
|
|
||||||
/// Start (or replace) the keep-alive Live Activity for the given app.
|
|
||||||
static func start(appName: String, bundleID: String) {
|
|
||||||
#if canImport(ActivityKit)
|
|
||||||
guard #available(iOS 16.1, *) else { return }
|
|
||||||
startActivity(appName: appName, bundleID: bundleID)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Update the app name shown by the current Live Activity, if any.
|
|
||||||
static func update(appName: String) {
|
|
||||||
#if canImport(ActivityKit)
|
|
||||||
guard #available(iOS 16.1, *) else { return }
|
|
||||||
updateActivity(appName: appName)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/// End the current keep-alive Live Activity, if any.
|
|
||||||
static func end() {
|
|
||||||
#if canImport(ActivityKit)
|
|
||||||
guard #available(iOS 16.1, *) else { return }
|
|
||||||
endActivity()
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/// End any keep-alive activities left running by a previous launch (for
|
|
||||||
/// example if the app was force-quit or crashed mid-hold). Call this once at
|
|
||||||
/// startup, when no hold is active.
|
|
||||||
static func endStaleActivities() {
|
|
||||||
#if canImport(ActivityKit)
|
|
||||||
guard #available(iOS 16.1, *) else { return }
|
|
||||||
for activity in Activity<KeepAliveActivityAttributes>.activities {
|
|
||||||
Task { await activity.end(nil, dismissalPolicy: .immediate) }
|
|
||||||
}
|
|
||||||
lock.lock()
|
|
||||||
storage = nil
|
|
||||||
lock.unlock()
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if canImport(ActivityKit)
|
|
||||||
@available(iOS 16.1, *)
|
|
||||||
private static func startActivity(appName: String, bundleID: String) {
|
|
||||||
guard ActivityAuthorizationInfo().areActivitiesEnabled else {
|
|
||||||
LogManager.shared.addInfoLog("Keep-alive Live Activity not started: Live Activities are disabled in Settings")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only one hold runs at a time, so make sure any stale activity is gone.
|
|
||||||
endActivity()
|
|
||||||
|
|
||||||
let attributes = KeepAliveActivityAttributes(appName: appName, bundleID: bundleID)
|
|
||||||
let state = KeepAliveActivityAttributes.ContentState(appName: appName)
|
|
||||||
|
|
||||||
do {
|
|
||||||
let activity = try Activity.request(
|
|
||||||
attributes: attributes,
|
|
||||||
content: ActivityContent(state: state, staleDate: nil)
|
|
||||||
)
|
|
||||||
lock.lock()
|
|
||||||
storage = activity
|
|
||||||
lock.unlock()
|
|
||||||
} catch {
|
|
||||||
LogManager.shared.addErrorLog("Keep-alive Live Activity failed to start: \(error.localizedDescription)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(iOS 16.1, *)
|
|
||||||
private static func updateActivity(appName: String) {
|
|
||||||
lock.lock()
|
|
||||||
let activity = storage as? Activity<KeepAliveActivityAttributes>
|
|
||||||
lock.unlock()
|
|
||||||
guard let activity else { return }
|
|
||||||
|
|
||||||
let state = KeepAliveActivityAttributes.ContentState(appName: appName)
|
|
||||||
Task {
|
|
||||||
await activity.update(ActivityContent(state: state, staleDate: nil))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(iOS 16.1, *)
|
|
||||||
private static func endActivity() {
|
|
||||||
lock.lock()
|
|
||||||
let activity = storage as? Activity<KeepAliveActivityAttributes>
|
|
||||||
storage = nil
|
|
||||||
lock.unlock()
|
|
||||||
guard let activity else { return }
|
|
||||||
|
|
||||||
Task {
|
|
||||||
await activity.end(nil, dismissalPolicy: .immediate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
//
|
|
||||||
// KeepAliveActivityAttributes.swift
|
|
||||||
// StikDebug
|
|
||||||
//
|
|
||||||
// Shared between the app (which starts/updates/ends the activity) and the
|
|
||||||
// widget extension (which renders it in the Dynamic Island / on the Lock
|
|
||||||
// Screen). Keep this file in the StikDebugShared group so both targets compile
|
|
||||||
// the same type.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
#if canImport(ActivityKit)
|
|
||||||
import ActivityKit
|
|
||||||
|
|
||||||
@available(iOS 16.1, *)
|
|
||||||
struct KeepAliveActivityAttributes: ActivityAttributes {
|
|
||||||
/// The parts of the activity that change while it is live.
|
|
||||||
struct ContentState: Codable, Hashable {
|
|
||||||
/// The display name of the app currently being held alive.
|
|
||||||
var appName: String
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The app being held alive when the activity started.
|
|
||||||
var appName: String
|
|
||||||
/// The bundle identifier of that app.
|
|
||||||
var bundleID: String
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>NSExtension</key>
|
|
||||||
<dict>
|
|
||||||
<key>NSExtensionPointIdentifier</key>
|
|
||||||
<string>com.apple.widgetkit-extension</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
//
|
|
||||||
// KeepAliveLiveActivityWidget.swift
|
|
||||||
// StikDebugWidgets
|
|
||||||
//
|
|
||||||
// Live Activity presentation for the background keep-alive session. Shows the
|
|
||||||
// held app in the Dynamic Island (compact, expanded, and minimal) and on the
|
|
||||||
// Lock Screen.
|
|
||||||
//
|
|
||||||
|
|
||||||
import WidgetKit
|
|
||||||
import SwiftUI
|
|
||||||
import ActivityKit
|
|
||||||
|
|
||||||
@available(iOS 16.1, *)
|
|
||||||
struct KeepAliveLiveActivityWidget: Widget {
|
|
||||||
var body: some WidgetConfiguration {
|
|
||||||
ActivityConfiguration(for: KeepAliveActivityAttributes.self) { context in
|
|
||||||
// Lock Screen / banner presentation.
|
|
||||||
KeepAliveLockScreenView(appName: context.state.appName)
|
|
||||||
.activityBackgroundTint(Color.black.opacity(0.55))
|
|
||||||
.activitySystemActionForegroundColor(.green)
|
|
||||||
} dynamicIsland: { context in
|
|
||||||
DynamicIsland {
|
|
||||||
DynamicIslandExpandedRegion(.leading) {
|
|
||||||
Image(systemName: "bolt.circle.fill")
|
|
||||||
.font(.title2)
|
|
||||||
.foregroundStyle(.green)
|
|
||||||
.padding(.leading, 4)
|
|
||||||
}
|
|
||||||
DynamicIslandExpandedRegion(.trailing) {
|
|
||||||
Text("JIT")
|
|
||||||
.font(.caption.weight(.bold))
|
|
||||||
.foregroundStyle(.green)
|
|
||||||
.padding(.trailing, 4)
|
|
||||||
}
|
|
||||||
DynamicIslandExpandedRegion(.center) {
|
|
||||||
Text(context.state.appName)
|
|
||||||
.font(.headline)
|
|
||||||
.lineLimit(1)
|
|
||||||
.minimumScaleFactor(0.7)
|
|
||||||
}
|
|
||||||
DynamicIslandExpandedRegion(.bottom) {
|
|
||||||
Text("Held alive in the background")
|
|
||||||
.font(.caption)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
}
|
|
||||||
} compactLeading: {
|
|
||||||
Image(systemName: "bolt.circle.fill")
|
|
||||||
.foregroundStyle(.green)
|
|
||||||
} compactTrailing: {
|
|
||||||
Text(context.state.appName)
|
|
||||||
.font(.caption2)
|
|
||||||
.lineLimit(1)
|
|
||||||
.frame(maxWidth: 64)
|
|
||||||
} minimal: {
|
|
||||||
Image(systemName: "bolt.circle.fill")
|
|
||||||
.foregroundStyle(.green)
|
|
||||||
}
|
|
||||||
.keylineTint(.green)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(iOS 16.1, *)
|
|
||||||
private struct KeepAliveLockScreenView: View {
|
|
||||||
let appName: String
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
HStack(spacing: 12) {
|
|
||||||
Image(systemName: "bolt.circle.fill")
|
|
||||||
.font(.title)
|
|
||||||
.foregroundStyle(.green)
|
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
|
||||||
Text("Keeping \(appName) alive")
|
|
||||||
.font(.headline)
|
|
||||||
.lineLimit(1)
|
|
||||||
.minimumScaleFactor(0.7)
|
|
||||||
Text("Held in the background")
|
|
||||||
.font(.caption)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(minLength: 0)
|
|
||||||
}
|
|
||||||
.padding()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
//
|
|
||||||
// StikDebugWidgetsBundle.swift
|
|
||||||
// StikDebugWidgets
|
|
||||||
//
|
|
||||||
// Widget extension bundle. Hosts the keep-alive Live Activity so it can be
|
|
||||||
// rendered in the Dynamic Island and on the Lock Screen.
|
|
||||||
//
|
|
||||||
|
|
||||||
import WidgetKit
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
@main
|
|
||||||
struct StikDebugWidgetsBundle: WidgetBundle {
|
|
||||||
var body: some Widget {
|
|
||||||
KeepAliveLiveActivityWidget()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue