Commit 7f7333dc authored by yqz's avatar yqz

widget 1001

parent aa7e9222
...@@ -7,9 +7,22 @@ ...@@ -7,9 +7,22 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
0496DEF32D9E3F58005B2834 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04BD915D2D9D68AD00055CEB /* WidgetKit.framework */; };
0496DEF42D9E3F58005B2834 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04BD915F2D9D68AD00055CEB /* SwiftUI.framework */; };
0496DEFF2D9E3F59005B2834 /* widgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0496DEF22D9E3F57005B2834 /* widgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
3A00E856852A8783E544CD7D /* Pods_PhoneManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6028F60B696E2F97EAA2325C /* Pods_PhoneManager.framework */; }; 3A00E856852A8783E544CD7D /* Pods_PhoneManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6028F60B696E2F97EAA2325C /* Pods_PhoneManager.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
0496DEFD2D9E3F59005B2834 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = EB388E532D8A61A800629B0D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0496DEF12D9E3F57005B2834;
remoteInfo = widgetExtension;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
04BD916E2D9D68AF00055CEB /* Embed Foundation Extensions */ = { 04BD916E2D9D68AF00055CEB /* Embed Foundation Extensions */ = {
isa = PBXCopyFilesBuildPhase; isa = PBXCopyFilesBuildPhase;
...@@ -17,6 +30,7 @@ ...@@ -17,6 +30,7 @@
dstPath = ""; dstPath = "";
dstSubfolderSpec = 13; dstSubfolderSpec = 13;
files = ( files = (
0496DEFF2D9E3F59005B2834 /* widgetExtension.appex in Embed Foundation Extensions */,
); );
name = "Embed Foundation Extensions"; name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
...@@ -24,6 +38,8 @@ ...@@ -24,6 +38,8 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
0496DEF22D9E3F57005B2834 /* widgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = widgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
0496DF042D9E3FA7005B2834 /* widgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = widgetExtension.entitlements; sourceTree = "<group>"; };
04BD915D2D9D68AD00055CEB /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; 04BD915D2D9D68AD00055CEB /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
04BD915F2D9D68AD00055CEB /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; 04BD915F2D9D68AD00055CEB /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
295785B9009F20AC4C1C36C4 /* Pods-PhoneManager.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PhoneManager.debug.xcconfig"; path = "Target Support Files/Pods-PhoneManager/Pods-PhoneManager.debug.xcconfig"; sourceTree = "<group>"; }; 295785B9009F20AC4C1C36C4 /* Pods-PhoneManager.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PhoneManager.debug.xcconfig"; path = "Target Support Files/Pods-PhoneManager/Pods-PhoneManager.debug.xcconfig"; sourceTree = "<group>"; };
...@@ -33,6 +49,13 @@ ...@@ -33,6 +49,13 @@
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
0496DF032D9E3F59005B2834 /* Exceptions for "widget" folder in "widgetExtension" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 0496DEF12D9E3F57005B2834 /* widgetExtension */;
};
EB388E6D2D8A61AA00629B0D /* Exceptions for "PhoneManager" folder in "PhoneManager" target */ = { EB388E6D2D8A61AA00629B0D /* Exceptions for "PhoneManager" folder in "PhoneManager" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet; isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = ( membershipExceptions = (
...@@ -43,6 +66,14 @@ ...@@ -43,6 +66,14 @@
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
/* Begin PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFileSystemSynchronizedRootGroup section */
0496DEF52D9E3F58005B2834 /* widget */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
0496DF032D9E3F59005B2834 /* Exceptions for "widget" folder in "widgetExtension" target */,
);
path = widget;
sourceTree = "<group>";
};
EB388E5D2D8A61A800629B0D /* PhoneManager */ = { EB388E5D2D8A61A800629B0D /* PhoneManager */ = {
isa = PBXFileSystemSynchronizedRootGroup; isa = PBXFileSystemSynchronizedRootGroup;
exceptions = ( exceptions = (
...@@ -54,6 +85,15 @@ ...@@ -54,6 +85,15 @@
/* End PBXFileSystemSynchronizedRootGroup section */ /* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
0496DEEF2D9E3F57005B2834 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0496DEF42D9E3F58005B2834 /* SwiftUI.framework in Frameworks */,
0496DEF32D9E3F58005B2834 /* WidgetKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
EB388E582D8A61A800629B0D /* Frameworks */ = { EB388E582D8A61A800629B0D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
...@@ -87,7 +127,9 @@ ...@@ -87,7 +127,9 @@
EB388E522D8A61A800629B0D = { EB388E522D8A61A800629B0D = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0496DF042D9E3FA7005B2834 /* widgetExtension.entitlements */,
EB388E5D2D8A61A800629B0D /* PhoneManager */, EB388E5D2D8A61A800629B0D /* PhoneManager */,
0496DEF52D9E3F58005B2834 /* widget */,
EB388E5C2D8A61A800629B0D /* Products */, EB388E5C2D8A61A800629B0D /* Products */,
CB2ACD1E9442B4500087E831 /* Pods */, CB2ACD1E9442B4500087E831 /* Pods */,
27ECDADD9059AB5043B8E1E9 /* Frameworks */, 27ECDADD9059AB5043B8E1E9 /* Frameworks */,
...@@ -98,6 +140,7 @@ ...@@ -98,6 +140,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
EB388E5B2D8A61A800629B0D /* PhoneManager.app */, EB388E5B2D8A61A800629B0D /* PhoneManager.app */,
0496DEF22D9E3F57005B2834 /* widgetExtension.appex */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -105,6 +148,28 @@ ...@@ -105,6 +148,28 @@
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
0496DEF12D9E3F57005B2834 /* widgetExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0496DF022D9E3F59005B2834 /* Build configuration list for PBXNativeTarget "widgetExtension" */;
buildPhases = (
0496DEEE2D9E3F57005B2834 /* Sources */,
0496DEEF2D9E3F57005B2834 /* Frameworks */,
0496DEF02D9E3F57005B2834 /* Resources */,
);
buildRules = (
);
dependencies = (
);
fileSystemSynchronizedGroups = (
0496DEF52D9E3F58005B2834 /* widget */,
);
name = widgetExtension;
packageProductDependencies = (
);
productName = widgetExtension;
productReference = 0496DEF22D9E3F57005B2834 /* widgetExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
EB388E5A2D8A61A800629B0D /* PhoneManager */ = { EB388E5A2D8A61A800629B0D /* PhoneManager */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = EB388E6E2D8A61AA00629B0D /* Build configuration list for PBXNativeTarget "PhoneManager" */; buildConfigurationList = EB388E6E2D8A61AA00629B0D /* Build configuration list for PBXNativeTarget "PhoneManager" */;
...@@ -119,6 +184,7 @@ ...@@ -119,6 +184,7 @@
buildRules = ( buildRules = (
); );
dependencies = ( dependencies = (
0496DEFE2D9E3F59005B2834 /* PBXTargetDependency */,
); );
fileSystemSynchronizedGroups = ( fileSystemSynchronizedGroups = (
EB388E5D2D8A61A800629B0D /* PhoneManager */, EB388E5D2D8A61A800629B0D /* PhoneManager */,
...@@ -138,6 +204,9 @@ ...@@ -138,6 +204,9 @@
LastSwiftUpdateCheck = 1620; LastSwiftUpdateCheck = 1620;
LastUpgradeCheck = 1620; LastUpgradeCheck = 1620;
TargetAttributes = { TargetAttributes = {
0496DEF12D9E3F57005B2834 = {
CreatedOnToolsVersion = 16.2;
};
EB388E5A2D8A61A800629B0D = { EB388E5A2D8A61A800629B0D = {
CreatedOnToolsVersion = 16.2; CreatedOnToolsVersion = 16.2;
LastSwiftMigration = 1620; LastSwiftMigration = 1620;
...@@ -159,11 +228,19 @@ ...@@ -159,11 +228,19 @@
projectRoot = ""; projectRoot = "";
targets = ( targets = (
EB388E5A2D8A61A800629B0D /* PhoneManager */, EB388E5A2D8A61A800629B0D /* PhoneManager */,
0496DEF12D9E3F57005B2834 /* widgetExtension */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
0496DEF02D9E3F57005B2834 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
EB388E592D8A61A800629B0D /* Resources */ = { EB388E592D8A61A800629B0D /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
...@@ -216,6 +293,13 @@ ...@@ -216,6 +293,13 @@
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
0496DEEE2D9E3F57005B2834 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
EB388E572D8A61A800629B0D /* Sources */ = { EB388E572D8A61A800629B0D /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
...@@ -225,7 +309,89 @@ ...@@ -225,7 +309,89 @@
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
0496DEFE2D9E3F59005B2834 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0496DEF12D9E3F57005B2834 /* widgetExtension */;
targetProxy = 0496DEFD2D9E3F59005B2834 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
0496DF002D9E3F59005B2834 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = widgetExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6K23946NQ5;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = widget/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = widget;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.app.phonemanager.bswidget;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = phonemanager_widget_dev;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
0496DF012D9E3F59005B2834 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = widgetExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6K23946NQ5;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = widget/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = widget;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.app.phonemanager.bswidget;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = phonemanager_widget_dev;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
EB388E6F2D8A61AA00629B0D /* Debug */ = { EB388E6F2D8A61AA00629B0D /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 295785B9009F20AC4C1C36C4 /* Pods-PhoneManager.debug.xcconfig */; baseConfigurationReference = 295785B9009F20AC4C1C36C4 /* Pods-PhoneManager.debug.xcconfig */;
...@@ -435,6 +601,15 @@ ...@@ -435,6 +601,15 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
0496DF022D9E3F59005B2834 /* Build configuration list for PBXNativeTarget "widgetExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0496DF002D9E3F59005B2834 /* Debug */,
0496DF012D9E3F59005B2834 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
EB388E562D8A61A800629B0D /* Build configuration list for PBXProject "PhoneManager" */ = { EB388E562D8A61A800629B0D /* Build configuration list for PBXProject "PhoneManager" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
......
...@@ -28,6 +28,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ...@@ -28,6 +28,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
window?.makeKeyAndVisible() window?.makeKeyAndVisible()
} }
let battery = WidgetPublicModel.battery()
let storage = WidgetPublicModel.UseDiskSpace() * 100
widgetAppgourp.share.PushWidgetData(battery: Int(battery), storage: Int(storage))
return true return true
} }
...@@ -69,7 +72,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ...@@ -69,7 +72,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
safeHeight = UIApplication.shared.delegate?.window??.safeAreaInsets.bottom ?? 0 safeHeight = UIApplication.shared.delegate?.window??.safeAreaInsets.bottom ?? 0
}else { }else {
safeHeight = 0 safeHeight = 0
} }
} }
......
...@@ -39,10 +39,8 @@ class ChargeViewController:BaseViewController { ...@@ -39,10 +39,8 @@ class ChargeViewController:BaseViewController {
if let cModel = model as? ChargeViewCollectionModel { if let cModel = model as? ChargeViewCollectionModel {
let vc:ChargeInfoViewController = ChargeInfoViewController(model: cModel, type: ChargeInfoViewController.ChargeInfoType.setting) let vc:ChargeInfoViewController = ChargeInfoViewController(model: cModel, type: ChargeInfoViewController.ChargeInfoType.setting)
self.navigationController?.pushViewController(vc, animated: true) self.navigationController?.pushViewController(vc, animated: true)
} }
} }
} }
......
...@@ -21,7 +21,7 @@ class SecretSetViewController: BaseViewController, UITextFieldDelegate { ...@@ -21,7 +21,7 @@ class SecretSetViewController: BaseViewController, UITextFieldDelegate {
if secretType == .create { if secretType == .create {
setTitle.text = "Create New PlN" setTitle.text = "Create New PlN"
}else{ }else{
setTitle.text = "Please Enter PlN"
} }
} }
...@@ -41,7 +41,16 @@ class SecretSetViewController: BaseViewController, UITextFieldDelegate { ...@@ -41,7 +41,16 @@ class SecretSetViewController: BaseViewController, UITextFieldDelegate {
didSet { didSet {
collect.reloadData() collect.reloadData()
if Secret.count == 4 { if Secret.count == 4 {
UserDefaults.standard.set(Secret, forKey: SecretViewController.psKey) if secretType == .verify {
let Ps:String = UserDefaults.standard.object(forKey: SecretViewController.psKey) as? String ?? ""
if Ps != Secret {
alert("Pin Verification Failed")
Secret = ""
return
}
}else{
UserDefaults.standard.set(Secret, forKey: SecretViewController.psKey)
}
guard Callback != nil else { guard Callback != nil else {
return return
} }
...@@ -57,7 +66,7 @@ class SecretSetViewController: BaseViewController, UITextFieldDelegate { ...@@ -57,7 +66,7 @@ class SecretSetViewController: BaseViewController, UITextFieldDelegate {
view.addSubview(collect) view.addSubview(collect)
setInfo.snp.makeConstraints { make in setInfo.snp.makeConstraints { make in
make.centerX.equalToSuperview() make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(62) make.top.equalTo(titleView.snp.bottom).offset(62)
} }
setTitle.snp.makeConstraints { make in setTitle.snp.makeConstraints { make in
make.centerX.equalToSuperview() make.centerX.equalToSuperview()
......
//
// SecretShowImgVideoController.swift
// PhoneManager
//
// Created by edy on 2025/4/3.
//
import UIKit
class SecretShowImgVideoController: BaseViewController {
var imageVideoPath:String = ""
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
showPlay()
}
private func setUI( _ icon:UIImage) -> Void {
showImage.snp.remakeConstraints { make in
make.left.right.equalToSuperview().inset(24)
make.top.equalTo(self.titleView.snp.bottom).offset(20)
make.height.equalTo(self.showImage.snp.width).multipliedBy(icon.size.height/icon.size.width)
}
}
private func showPlay() -> Void {
if imageVideoPath.hasSuffix(".png") {
self.showImage.isHidden = false
imageVideoPath.loadPhotoOrVideo({[weak self] dur, icon in
self?.showImage.image = icon
self?.setUI(icon)
})
}else{
player.snp.makeConstraints { make in
make.left.right.equalToSuperview().inset(20)
make.top.equalTo(self.titleView.snp.bottom).offset(20)
make.bottom.equalToSuperview().offset(-40)
}
player.isHidden = false
let url = "SecretIm".document().appendingPathComponent(imageVideoPath)
player.playVideo(from: url)
}
}
private lazy var showImage: UIImageView = {
let img = UIImageView()
img.contentMode = .scaleAspectFill
img.isHidden = true
view.addSubview(img)
return img
}()
private lazy var player: SecretVideoPlayer = {
let p = SecretVideoPlayer()
view.addSubview(p)
p.layer.cornerRadius = 8
p.clipsToBounds = true
p.isHidden = true
return p
}()
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
player.pause()
}
}
...@@ -106,6 +106,7 @@ class SecretViewController: BaseViewController { ...@@ -106,6 +106,7 @@ class SecretViewController: BaseViewController {
let set = SecretSetViewController() let set = SecretSetViewController()
set.Callback = { suc in set.Callback = { suc in
self?.isVerify = suc self?.isVerify = suc
sender.isSelected = suc
} }
self?.navigationController?.pushViewController(set, animated: true) self?.navigationController?.pushViewController(set, animated: true)
} }
...@@ -114,6 +115,16 @@ class SecretViewController: BaseViewController { ...@@ -114,6 +115,16 @@ class SecretViewController: BaseViewController {
} }
alert.show() alert.show()
}else{ }else{
if isVerify == false {
let set = SecretSetViewController()
set.secretType = .verify
set.Callback = {[weak self] suc in
self?.isVerify = suc
sender.isSelected = suc
}
self.navigationController?.pushViewController(set, animated: true)
return
}
sender.isSelected = !sender.isSelected sender.isSelected = !sender.isSelected
isVerify = sender.isSelected; isVerify = sender.isSelected;
} }
...@@ -250,17 +261,16 @@ extension SecretViewController : UICollectionViewDelegate,UICollectionViewDataSo ...@@ -250,17 +261,16 @@ extension SecretViewController : UICollectionViewDelegate,UICollectionViewDataSo
cell.clipsToBounds = true cell.clipsToBounds = true
cell.isSelect = selectArray.contains((indexPath.row)) cell.isSelect = selectArray.contains((indexPath.row))
cell.imageText = data[indexPath.row] cell.imageText = data[indexPath.row]
cell.callback = { [weak self] in
self?.selectImgVideo(indexPath.row)
}
return cell return cell
} }
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if selectArray.contains((indexPath.row)) { let play = SecretShowImgVideoController()
selectArray.remove((indexPath.row)) play.imageVideoPath = data[indexPath.row]
}else{ self.navigationController?.pushViewController(play, animated: true)
selectArray.add((indexPath.row))
}
seletedAllBtn.isSelected = selectArray.count == data.count
collectionView.reloadData()
} }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
...@@ -290,6 +300,16 @@ extension SecretViewController : UICollectionViewDelegate,UICollectionViewDataSo ...@@ -290,6 +300,16 @@ extension SecretViewController : UICollectionViewDelegate,UICollectionViewDataSo
extension SecretViewController : UIImagePickerControllerDelegate , UINavigationControllerDelegate{ extension SecretViewController : UIImagePickerControllerDelegate , UINavigationControllerDelegate{
private func selectImgVideo(_ row:Int) -> Void {
if selectArray.contains((row)) {
selectArray.remove((row))
}else{
selectArray.add((row))
}
seletedAllBtn.isSelected = selectArray.count == data.count
secretCollect.reloadData()
}
private func SecretPhotos(_ idx:Int, _ data:Any ) -> Void { private func SecretPhotos(_ idx:Int, _ data:Any ) -> Void {
if let asset:[PhotoAsset] = data as? [PhotoAsset] { if let asset:[PhotoAsset] = data as? [PhotoAsset] {
var assetdels:[PHAsset] = [] var assetdels:[PHAsset] = []
......
...@@ -104,7 +104,7 @@ class SecretActionView: UIViewController { ...@@ -104,7 +104,7 @@ class SecretActionView: UIViewController {
carma.contentHorizontalAlignment = .leading carma.contentHorizontalAlignment = .leading
carma.layer.cornerRadius = 12 carma.layer.cornerRadius = 12
carma.tag = 0x10; carma.tag = 0x10;
carma.setTitle("Instantly Detect Similar Photos", for: .normal) carma.setTitle("Take photos or videos", for: .normal)
carma.setTitleColor(.black, for: .normal) carma.setTitleColor(.black, for: .normal)
carma.addTarget(self, action: #selector(actionTouch(_:)), for: .touchUpInside) carma.addTarget(self, action: #selector(actionTouch(_:)), for: .touchUpInside)
carma.imageEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0) carma.imageEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)
...@@ -121,7 +121,7 @@ class SecretActionView: UIViewController { ...@@ -121,7 +121,7 @@ class SecretActionView: UIViewController {
Photo.contentHorizontalAlignment = .leading Photo.contentHorizontalAlignment = .leading
Photo.layer.cornerRadius = 12 Photo.layer.cornerRadius = 12
Photo.tag = 0x11; Photo.tag = 0x11;
Photo.setTitle("No Ads and Limits", for: .normal) Photo.setTitle("Import photos or videos", for: .normal)
Photo.setTitleColor(.black, for: .normal) Photo.setTitleColor(.black, for: .normal)
Photo.addTarget(self, action: #selector(actionTouch(_:)), for: .touchUpInside) Photo.addTarget(self, action: #selector(actionTouch(_:)), for: .touchUpInside)
Photo.imageEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0) Photo.imageEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)
...@@ -132,7 +132,7 @@ class SecretActionView: UIViewController { ...@@ -132,7 +132,7 @@ class SecretActionView: UIViewController {
lazy var cancelBtn: UIButton = { lazy var cancelBtn: UIButton = {
let can = UIButton(type: .custom) let can = UIButton(type: .custom)
can.setTitle("Oldest", for: .normal) can.setTitle("Cancel", for: .normal)
can.backgroundColor = .white can.backgroundColor = .white
can.tag = 0x12 can.tag = 0x12
can.addTarget(self, action: #selector(actionTouch(_:)), for: .touchUpInside) can.addTarget(self, action: #selector(actionTouch(_:)), for: .touchUpInside)
......
...@@ -14,7 +14,15 @@ class SecretFirstCell: UICollectionViewCell { ...@@ -14,7 +14,15 @@ class SecretFirstCell: UICollectionViewCell {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
setUI() setUI()
backgroundColor = UIColor.random }
var callback:(()->Void)?
@objc func SelectTouch() -> Void {
guard callback != nil else {
return
}
callback!()
} }
private func setUI() -> Void { private func setUI() -> Void {
...@@ -63,7 +71,7 @@ class SecretFirstCell: UICollectionViewCell { ...@@ -63,7 +71,7 @@ class SecretFirstCell: UICollectionViewCell {
let info = UIButton(type: .custom) let info = UIButton(type: .custom)
info.setImage(UIImage(named: "home_info_norl"), for: .normal) info.setImage(UIImage(named: "home_info_norl"), for: .normal)
info.setImage(UIImage(named: "home_info_seleted"), for: .selected) info.setImage(UIImage(named: "home_info_seleted"), for: .selected)
info.isUserInteractionEnabled = false info.addTarget(self, action: #selector(SelectTouch), for: .touchUpInside)
addSubview(info) addSubview(info)
return info return info
}() }()
...@@ -75,6 +83,7 @@ class SecretFirstCell: UICollectionViewCell { ...@@ -75,6 +83,7 @@ class SecretFirstCell: UICollectionViewCell {
private lazy var infoView: UIImageView = { private lazy var infoView: UIImageView = {
let info = UIImageView() let info = UIImageView()
info.contentMode = .scaleAspectFill info.contentMode = .scaleAspectFill
info.image = UIImage.Clear()
addSubview(info) addSubview(info)
return info return info
}() }()
......
//
// SecretVideoPlayer.swift
// PhoneManager
//
// Created by edy on 2025/4/3.
//
import UIKit
import AVFoundation
class SecretVideoPlayer: UIView {
private var player: AVPlayer?
var isLooping = false
enum playState {
case start
case playing
case pause
case end
}
var state:playState = .start
override init(frame: CGRect) {
super.init(frame: frame)
setupPlayerLayer()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupPlayerLayer()
}
@objc func tapClick() -> Void {
if state == .pause || state == .start {
resume()
state = .playing
}else if state == .end {
state = .playing
player?.seek(to: CMTime.zero)
resume()
}
else{
state = .pause
pause()
}
}
private func setupPlayerLayer() {
let playerLayer = AVPlayerLayer()
playerLayer.videoGravity = .resizeAspect
layer.addSublayer(playerLayer)
let tap = UITapGestureRecognizer(target: self, action: #selector(tapClick))
self.addGestureRecognizer(tap)
}
override func layoutSubviews() {
super.layoutSubviews()
if let playerLayer = layer.sublayers?.first as? AVPlayerLayer {
playerLayer.frame = bounds
}
}
func playVideo(from url: URL) {
removeObservers()
player = AVPlayer(url: url)
if let playerLayer = layer.sublayers?.first as? AVPlayerLayer {
playerLayer.player = player
}
NotificationCenter.default.addObserver(
self,
selector: #selector(playerItemDidReachEnd),
name: .AVPlayerItemDidPlayToEndTime,
object: player?.currentItem
)
state = .playing
player?.play()
}
// 播放完成回调
@objc private func playerItemDidReachEnd(notification: Notification) {
if isLooping {
player?.seek(to: CMTime.zero)
player?.play()
}
state = .end
}
// 暂停播放
func pause() {
state = .pause
player?.pause()
}
// 继续播放
func resume() {
state = .playing
player?.play()
}
// 移除观察者
private func removeObservers() {
NotificationCenter.default.removeObserver(
self,
name: .AVPlayerItemDidPlayToEndTime,
object: nil
)
}
// 清理资源
deinit {
removeObservers()
}
}
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
import UIKit import UIKit
import Foundation import Foundation
import Darwin import Darwin
import WidgetKit
class WidgetPublicModel: NSObject { class WidgetPublicModel: NSObject {
...@@ -19,7 +20,14 @@ class WidgetPublicModel: NSObject { ...@@ -19,7 +20,14 @@ class WidgetPublicModel: NSObject {
return batt return batt
} }
public class func getDiskSpace() -> (Int64,Int64) { public class func UseDiskSpace() -> CGFloat {
let disk = getDiskSpace()
let use = disk.0 - disk.1
let useP:CGFloat = CGFloat(use) / CGFloat(disk.0)
return useP
}
private class func getDiskSpace() -> (Int64,Int64) {
let total = TotalDiskSize() let total = TotalDiskSize()
let available = AvailableDiskSize() let available = AvailableDiskSize()
return (total,available) return (total,available)
...@@ -49,3 +57,26 @@ class WidgetPublicModel: NSObject { ...@@ -49,3 +57,26 @@ class WidgetPublicModel: NSObject {
} }
} }
class widgetAppgourp: NSObject {
static let share = widgetAppgourp()
func PushWidgetData(_ widget:Int = 0 , battery:Int , storage:Int ) -> Void {
let data = WidgetData(userId: "", widget: widget, battery: battery, widgetStorage: storage)
if let sharedDefaults = UserDefaults(suiteName: "group.com.app.phonemanager") {
let encodedData = try? JSONEncoder().encode(data)
sharedDefaults.set(encodedData, forKey: "widgetSharedData")
}
WidgetCenter.shared.reloadAllTimelines()
}
}
struct WidgetData: Codable {
var userId: String
var widget: Int
var battery: Int
var widgetStorage :Int
}
...@@ -17,9 +17,7 @@ class WidgetBatteryStView: UIView ,BatteryStatusDelegate { ...@@ -17,9 +17,7 @@ class WidgetBatteryStView: UIView ,BatteryStatusDelegate {
staray.isHidden = true staray.isHidden = true
}else{ }else{
widgetT.text = "Storage" widgetT.text = "Storage"
let disk = WidgetPublicModel.getDiskSpace() let useP = WidgetPublicModel.UseDiskSpace()
let use = disk.0 - disk.1
let useP = Float(use) / Float(disk.0)
widgetR.text = String(format: "%.0f%%", useP * 100) widgetR.text = String(format: "%.0f%%", useP * 100)
widgetInfo.image = UIImage(named: "img_storage_widgets") widgetInfo.image = UIImage(named: "img_storage_widgets")
staray.isHidden = false staray.isHidden = false
...@@ -78,9 +76,7 @@ class WidgetBatteryStView: UIView ,BatteryStatusDelegate { ...@@ -78,9 +76,7 @@ class WidgetBatteryStView: UIView ,BatteryStatusDelegate {
let end:CGFloat = CGFloat(WidgetPublicModel.battery() / 100.0) let end:CGFloat = CGFloat(WidgetPublicModel.battery() / 100.0)
endangle = -Double.pi/2.0 + CGFloat(Double.pi * 2.0 * end) endangle = -Double.pi/2.0 + CGFloat(Double.pi * 2.0 * end)
}else{ }else{
let disk = WidgetPublicModel.getDiskSpace() let useP:CGFloat = WidgetPublicModel.UseDiskSpace()
let use = disk.0 - disk.1
let useP:CGFloat = CGFloat(use) / CGFloat(disk.0)
endangle = -.pi/2.0 + CGFloat(Double.pi * 2.0 * useP) endangle = -.pi/2.0 + CGFloat(Double.pi * 2.0 * useP)
} }
path.addArc(withCenter: CGPoint(x: size.width/2.0, y: size.height/2.0), path.addArc(withCenter: CGPoint(x: size.width/2.0, y: size.height/2.0),
......
...@@ -34,10 +34,14 @@ class WidgetViewController: BaseViewController { ...@@ -34,10 +34,14 @@ class WidgetViewController: BaseViewController {
} }
@objc func setWidgetTouch() -> Void { @objc func setWidgetTouch() -> Void {
let battery = WidgetPublicModel.battery()
let storage = WidgetPublicModel.UseDiskSpace() * 100
var widgetIdx = 0
widgetIdx = (widgets == .battery ? 0 : 1) * 10 + widgetMode
widgetAppgourp.share.PushWidgetData(widgetIdx, battery: Int(battery), storage: Int(storage))
alert("Set Widget Successfully")
} }
func setUI() -> Void { func setUI() -> Void {
titleL.snp.makeConstraints { make in titleL.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15) make.left.equalToSuperview().offset(15)
......
...@@ -626,13 +626,14 @@ class PhotoAndVideoMananger { ...@@ -626,13 +626,14 @@ class PhotoAndVideoMananger {
class SecretPhotoManager: NSObject, PhotoPickerControllerDelegate , CameraControllerDelegate { class SecretPhotoManager: NSObject, PhotoPickerControllerDelegate , CameraControllerDelegate {
func cameraController(_ cameraController: HXPhotoPicker.CameraController, didFinishWithResult result: HXPhotoPicker.CameraController.Result, phAsset: PHAsset?, location: CLLocation?) { func cameraController(_ cameraController: HXPhotoPicker.CameraController, didFinishWithResult result: HXPhotoPicker.CameraController.Result, phAsset: PHAsset?, location: CLLocation?) {
switch result { switch result {
case .image(let image): case .image(let image):
let data = image.pngData() image.compressImage(0.7) {[weak self] image in
guard callback != nil else { return } let data = image.pngData()
callback!(0,data) guard self?.callback != nil else { return }
self?.callback!(0,data)
}
break break
case .video(let fileUrl): case .video(let fileUrl):
let data = NSData(contentsOf: fileUrl) let data = NSData(contentsOf: fileUrl)
......
...@@ -54,6 +54,16 @@ func weekFormatter() -> String { ...@@ -54,6 +54,16 @@ func weekFormatter() -> String {
return formatter.string(from: Date()) return formatter.string(from: Date())
} }
func alert(_ msg:String) -> Void {
let alertview = UIAlertController(title: nil, message: msg, preferredStyle: .alert)
guard let root = cWindow?.rootViewController else { return }
root.present(alertview, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alertview.dismiss(animated: true)
}
}
public func Print(_ items: Any...) { public func Print(_ items: Any...) {
#if DEBUG #if DEBUG
......
...@@ -9,6 +9,69 @@ import Foundation ...@@ -9,6 +9,69 @@ import Foundation
import UIKit import UIKit
import AVFoundation import AVFoundation
extension UIColor {
convenience init(_ hex:UInt32) {
self.init(hex, 1.0)
}
convenience init(_ hex:UInt32 , _ alpha:Float = 1.0) {
let red = Double((hex & 0xff0000) >> 16) / 255.0
let green = Double((hex & 0xff00) >> 8) / 255.0
let blue = Double((hex & 0xff) ) / 255.0
self.init(red: red, green: green, blue: blue, alpha: 1)
}
func generateImage() -> UIImage? {
let size = CGSize(width: 1, height: 1)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
defer { UIGraphicsEndImageContext() }
self.setFill()
UIRectFill(CGRect(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
}
extension UIImage {
class func Clear(_ color:UIColor = .clear) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
defer { UIGraphicsEndImageContext() }
color.setFill()
UIRectFill(rect)
return UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
}
func compressImage(_ scale: CGFloat , comp:@escaping ((_ image:UIImage)->Void)) -> Void {
DispatchQueue.global().async {
let imageData = self.jpegData(compressionQuality: scale)
guard imageData != nil else {
return
}
let img = UIImage(data: imageData!) ?? UIImage.Clear()
DispatchQueue.main.async {
comp(img)
}
}
}
func resizeAndCompressImage(_ scale: CGFloat = 0.5) -> UIImage {
let size = self.size
let widthRatio = size.width * scale
let heightRatio = size.height * scale
let newSize = CGSize(width: widthRatio, height: heightRatio)
let rect = CGRect(origin: .zero, size: newSize)
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
self.draw(in: rect)
let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return resizedImage ?? UIImage.Clear()
}
}
extension String { extension String {
// 获取文档路径 // 获取文档路径
...@@ -21,14 +84,17 @@ extension String { ...@@ -21,14 +84,17 @@ extension String {
return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first ?? "" return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first ?? ""
} }
func loadPhotoOrVideo( _ pv:((Float64,UIImage)->Void) ) -> Void { func loadPhotoOrVideo( _ pv:@escaping ((Float64,UIImage)->Void) ) -> Void {
let path = self.af() + "/SecretIm/" let path = self.af() + "/SecretIm/"
let abe = path + self let abe = path + self
if self.hasSuffix(".png") { if self.hasSuffix(".png") {
guard let icon = UIImage(contentsOfFile: abe) else { guard let icon = UIImage(contentsOfFile: abe) else {
return pv(-1,UIImage()) pv(-1,UIImage.Clear())
return
}
icon.compressImage(0.5) { image in
pv(-1,image)
} }
return pv(-1,icon)
}else{ }else{
let url = "SecretIm".document().appendingPathComponent(self) let url = "SecretIm".document().appendingPathComponent(self)
let asset = AVAsset(url: url) let asset = AVAsset(url: url)
...@@ -37,12 +103,14 @@ extension String { ...@@ -37,12 +103,14 @@ extension String {
let duration = asset.duration let duration = asset.duration
do { do {
let cgImage = try imageGenerator.copyCGImage(at: CMTime(value: 0, timescale: 1), actualTime: nil) let cgImage = try imageGenerator.copyCGImage(at: CMTime(value: 0, timescale: 1), actualTime: nil)
pv(CMTimeGetSeconds(duration) ,UIImage(cgImage: cgImage)) let icon = UIImage(cgImage: cgImage);
icon.compressImage(0.5) { image in
pv(CMTimeGetSeconds(duration) ,image)
}
} catch { } catch {
pv(-1,UIImage() ) pv(-1,UIImage() )
} }
} }
} }
} }
...@@ -52,7 +120,7 @@ extension URL { ...@@ -52,7 +120,7 @@ extension URL {
// 获取 路径下所有文件 // 获取 路径下所有文件
func directorChildFile() -> [String] { func directorChildFile() -> [String] {
let fileManager = FileManager.default let fileManager = FileManager.default
let has = fileManager.fileExists(atPath: self.pathExtension ) _ = fileManager.fileExists(atPath: self.pathExtension )
do { do {
let fileNames = try fileManager.contentsOfDirectory(atPath: self.absoluteString) let fileNames = try fileManager.contentsOfDirectory(atPath: self.absoluteString)
var filesOnly: [String] = [] var filesOnly: [String] = []
......
...@@ -49,10 +49,10 @@ extension UIColor { ...@@ -49,10 +49,10 @@ extension UIColor {
} }
static var random: UIColor { static var random: UIColor {
let red = CGFloat.random(in: 0...1) let red = CGFloat.random(in: 0...1)
let green = CGFloat.random(in: 0...1) let green = CGFloat.random(in: 0...1)
let blue = CGFloat.random(in: 0...1) let blue = CGFloat.random(in: 0...1)
return UIColor(red: red, green: green, blue: blue, alpha: 1.0) return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
} }
} }
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_battery_widgets_blue.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_battery_widgets_blue@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_battery_widgets_blue@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_battery_widgets_white.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_battery_widgets_white@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_battery_widgets_white@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_storage_widgets_blue.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_storage_widgets_blue@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_storage_widgets_blue@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_storage_widgets_black.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_storage_widgets_black@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_storage_widgets_black@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
<?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>
//
// widget.swift
// widget
//
// Created by edy on 2025/4/3.
//
import WidgetKit
import SwiftUI
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), widgets: 0, widgetBattery: 0, widgetStorage: 0)
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> Void) {
let entry = loadSharedData()
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> Void) {
let entry = loadSharedData()
let timeline = Timeline(entries: [entry], policy: .after(Date().addingTimeInterval(120)))
completion(timeline)
}
private func loadSharedData() -> SimpleEntry {
guard let sharedDefaults = UserDefaults(suiteName: "group.com.app.phonemanager"),
let data:Data = sharedDefaults.object(forKey: "widgetSharedData") as? Data,
let decodedData = try? JSONDecoder().decode(WidgetData.self, from: data)
else {
return SimpleEntry(date: Date(), widgets: 0, widgetBattery: 0, widgetStorage: 0)
}
return SimpleEntry(date: Date(), widgets: decodedData.widget, widgetBattery: decodedData.battery, widgetStorage: decodedData.widgetStorage)
}
}
struct WidgetData: Codable {
var userId: String
var widget: Int
var battery: Int
var widgetStorage: Int
}
struct WidgetStyle : Codable {
var textColor : String
var lText : String
var backgound : String
var LineColor : String
var icon : String
var Angle : Double
}
struct SimpleEntry: TimelineEntry {
let date: Date
let widgets:Int
let widgetBattery:Int
let widgetStorage:Int
}
struct BatteryWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
ZStack {
Color(getwidgetStyle().backgound).ignoresSafeArea()
VStack {
HStack(alignment: .center) {
Text(getwidgetStyle().lText).frame(maxWidth: .infinity,maxHeight: .infinity,alignment: .topLeading).font(.system(size: 14)).foregroundColor(Color(getwidgetStyle().textColor))
VStack(alignment: .center, spacing: 2) {
Text(String(getwidgetStyle().Angle) + "%" ).frame(maxWidth: .infinity,maxHeight: .infinity,alignment: .topTrailing).font(.system(size: 14)).foregroundColor(Color(getwidgetStyle().textColor))
if entry.widgets / 10 == 1 {
Text("Used").frame(maxWidth: .infinity,alignment: .topTrailing).font(.system(size: 10)).foregroundColor(Color(getwidgetStyle().textColor)).padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 5))
}
}
}
ZStack {
Image(getwidgetStyle().icon)
ArcShape(startAngle: .degrees(-90), endAngle: .degrees(getwidgetStyle().Angle/100.0 * 360.0 - 90.0), clockwise: false)
.stroke(Color(getwidgetStyle().LineColor), style: StrokeStyle(lineWidth: 5, lineCap: .round) )
}
}.padding(EdgeInsets(top: 16, leading: 10, bottom: 30, trailing: 10))
}
}
func getwidgetStyle() -> WidgetStyle {
var icon = ""
var lt = "Battery"
var anag = 0
if entry.widgets / 10 == 0 {
if (entry.widgets % 10) != 2 {
icon = "img_battery_widgets"
}else{
icon = "img_battery_widgets_b"
}
anag = entry.widgetBattery
}else{
lt = "Storage"
if (entry.widgets % 10) != 2 {
icon = "img_storage_widgets"
}else{
icon = "img_storage_widgets_b"
}
anag = entry.widgetStorage
}
var tcolor = "FFFFFF"
var bg = "0082FF"
var line = "FFFFFF"
if entry.widgets % 10 == 0 {
} else if entry.widgets % 10 == 1 {
bg = "333333"
line = "0082FF"
}else{
line = "0082FF"
bg = "FFFFFF"
tcolor = "0082FF"
}
return WidgetStyle(textColor: tcolor, lText: lt, backgound: bg, LineColor: line ,icon:icon ,Angle: Double(anag))
}
}
struct ArcShape: Shape {
var startAngle: Angle
var endAngle: Angle
var clockwise: Bool
func path(in rect: CGRect) -> Path {
var path = Path()
let center = CGPoint(x: rect.midX, y: rect.midY)
let radius = min(rect.width, rect.height) / 2.0 - 3.0
path.addArc(
center: center,
radius: radius,
startAngle: startAngle,
endAngle: endAngle,
clockwise: clockwise
)
return path
}
}
struct BatteryWidget: Widget {
let kind: String = "BatteryWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
BatteryWidgetEntryView(entry: entry)
}.configurationDisplayName("").description("")
.supportedFamilies([.systemSmall , .systemMedium])
}
}
//
// widgetBundle.swift
// widget
//
// Created by edy on 2025/4/3.
//
import WidgetKit
import SwiftUI
@main
struct widgetBundle: WidgetBundle {
var body: some Widget {
BatteryWidget()
}
}
extension Color {
init(_ hex:String = "FFFFFF") {
let scanner = Scanner(string: hex)
scanner.currentIndex = hex.startIndex
var rgb:UInt64 = 0
scanner.scanHexInt64(&rgb)
let r = Double( (rgb & 0xff0000) >> 16) / 255.0
let g = Double( (rgb & 0xff00) >> 8) / 255.0
let b = Double( (rgb & 0xff)) / 255.0
self.init(red: r, green: g, blue: b)
}
}
<?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>com.apple.security.application-groups</key>
<array>
<string>group.com.app.phonemanager</string>
</array>
</dict>
</plist>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment