Skip to content

Commit b58554f

Browse files
author
DevelopLab
committed
1.Add com.apple.private.security.storage.AppDataContainers permission.
2.Settings plist file can save in sandbox. 3.Settings item can sync with plist file.
1 parent cabc864 commit b58554f

9 files changed

Lines changed: 311 additions & 55 deletions

AppDelegate.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
99
window = UIWindow(frame: UIScreen.main.bounds)
1010
window!.rootViewController = UINavigationController(rootViewController: RootViewController())
1111
window!.makeKeyAndVisible()
12+
// 加载配置文件
13+
SettingsUtils.instance
1214
return true
1315
}
1416

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ include $(THEOS)/makefiles/common.mk
77

88
APPLICATION_NAME = RebootTools
99

10-
RebootTools_FILES = AppDelegate.swift RootViewController.swift SettingsViewController.swift DeviceController.m
10+
RebootTools_FILES = AppDelegate.swift RootViewController.swift SettingsViewController.swift DeviceController.m PlistManagerUtils.swift SettingsUtils.swift
1111
RebootTools_FRAMEWORKS = UIKit CoreGraphics
1212
RebootTools_RESOURCES = Resources/Assets.xcassets
1313
$(APPLICATION_NAME)_SWIFT_BRIDGING_HEADER += $(APPLICATION_NAME)-Bridging-Header.h

PlistManagerUtils.swift

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,50 @@ import Foundation
33
class PlistManagerUtils {
44

55
// 单例实例
6-
static let shared = PlistManager(plistName: "userSettings")
6+
private static var instances: [String: PlistManagerUtils] = [:]
77

88
private var plistFileURL: URL
9+
private var plistExist: Bool = false
910
private var preferences: [String: Any]
1011
private var cachedChanges: [String: Any] = [:]
1112
private var isDirty = false
1213

14+
// 获取实例方法(支持多实例)
15+
static func instance(for plistName: String) -> PlistManagerUtils {
16+
// 如果实例已存在,则返回现有实例
17+
if let instance = instances[plistName] {
18+
return instance
19+
}
20+
21+
// 否则创建新的实例并存储
22+
let instance = PlistManagerUtils(plistName: plistName)
23+
instances[plistName] = instance
24+
return instance
25+
}
26+
1327
// 初始化 PlistManager,指定 plist 文件名
1428
private init(plistName: String) {
1529
// 获取沙盒中的 Preferences 目录路径
1630
let preferencesDirectory = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!
17-
self.plistFileURL = preferencesDirectory.appendingPathComponent("Preferences/\(plistName).plist")
31+
let preferencesPath = preferencesDirectory.appendingPathComponent("Preferences")
32+
self.plistFileURL = preferencesPath.appendingPathComponent("\(plistName).plist")
1833

1934
// 如果 plist 文件不存在,则创建一个空的文件
2035
if !FileManager.default.fileExists(atPath: plistFileURL.path) {
2136
preferences = [:]
2237
save()
38+
NSLog("Reboot Tools----> 创建配置文件")
39+
plistExist = false //增加一个标识,让外界知道这个配置文件是新创建的
2340
} else {
24-
preferences = loadPreferences()
41+
self.preferences = PlistManagerUtils.loadPreferences(from: plistFileURL)
42+
NSLog("Reboot Tools----> 加载已有创建文件")
43+
plistExist = true
2544
}
2645
}
2746

2847
// 加载 plist 文件中的数据
29-
private func loadPreferences() -> [String: Any] {
30-
guard let data = try? Data(contentsOf: plistFileURL),
48+
private static func loadPreferences(from url: URL) -> [String: Any] {
49+
guard let data = try? Data(contentsOf: url),
3150
let preferences = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any] else {
3251
return [:]
3352
}
@@ -39,53 +58,60 @@ class PlistManagerUtils {
3958
do {
4059
let data = try PropertyListSerialization.data(fromPropertyList: preferences, format: .xml, options: 0)
4160
try data.write(to: plistFileURL)
61+
NSLog("Reboot Tools----> Save successful Plist file path: \(plistFileURL.path)")
4262
} catch {
43-
print("Error saving preferences to plist: \(error.localizedDescription)")
63+
print("Reboot Tools----> Error saving preferences to plist: \(error.localizedDescription)")
4464
}
4565
}
66+
67+
68+
// 获取 plist 文件是否存在
69+
func isPlistExist() -> Bool {
70+
return plistExist
71+
}
4672

4773
// 获取指定 key 对应的 Int 值
48-
func getInt(forKey key: String, defaultValue: Int) -> Int {
74+
func getInt(key: String, defaultValue: Int) -> Int {
4975
return preferences[key] as? Int ?? defaultValue
5076
}
5177

5278
// 获取指定 key 对应的 Bool 值
53-
func getBool(forKey key: String, defaultValue: Bool) -> Bool {
79+
func getBool(key: String, defaultValue: Bool) -> Bool {
5480
return preferences[key] as? Bool ?? defaultValue
5581
}
5682

5783
// 获取指定 key 对应的 String 值
58-
func getString(forKey key: String, defaultValue: String) -> String {
84+
func getString(key: String, defaultValue: String) -> String {
5985
return preferences[key] as? String ?? defaultValue
6086
}
6187

6288
// 获取指定 key 对应的 Float 值
63-
func getFloat(forKey key: String, defaultValue: Float) -> Float {
89+
func getFloat(key: String, defaultValue: Float) -> Float {
6490
return preferences[key] as? Float ?? defaultValue
6591
}
6692

6793
// 获取指定 key 对应的 Double 值
68-
func getDouble(forKey key: String, defaultValue: Double) -> Double {
94+
func getDouble(key: String, defaultValue: Double) -> Double {
6995
return preferences[key] as? Double ?? defaultValue
7096
}
7197

7298
// 获取指定 key 对应的 Data 值
73-
func getData(forKey key: String, defaultValue: Data) -> Data {
99+
func getData(key: String, defaultValue: Data) -> Data {
74100
return preferences[key] as? Data ?? defaultValue
75101
}
76102

77103
// 获取指定 key 对应的 URL 值
78-
func getURL(forKey key: String, defaultValue: URL) -> URL {
104+
func getURL(key: String, defaultValue: URL) -> URL {
79105
return preferences[key] as? URL ?? defaultValue
80106
}
81107

82108
// 获取指定 key 对应的 Array 值
83-
func getArray(forKey key: String, defaultValue: [Any]) -> [Any] {
109+
func getArray(key: String, defaultValue: [Any]) -> [Any] {
84110
return preferences[key] as? [Any] ?? defaultValue
85111
}
86112

87113
// 获取指定 key 对应的 Dictionary 值
88-
func getDictionary(forKey key: String, defaultValue: [String: Any]) -> [String: Any] {
114+
func getDictionary(key: String, defaultValue: [String: Any]) -> [String: Any] {
89115
return preferences[key] as? [String: Any] ?? defaultValue
90116
}
91117

@@ -144,7 +170,7 @@ class PlistManagerUtils {
144170
}
145171

146172
// 删除指定 key 的数据
147-
func remove(forKey key: String) {
173+
func remove(key: String) {
148174
cachedChanges[key] = nil
149175
isDirty = true
150176
}
@@ -155,10 +181,14 @@ class PlistManagerUtils {
155181
try FileManager.default.removeItem(at: plistFileURL)
156182
preferences = [:]
157183
} catch {
158-
print("Error clearing plist file: \(error.localizedDescription)")
184+
print("Reboot Tools----> Error clearing plist file: \(error.localizedDescription)")
159185
}
160186
}
161187

188+
func commit() {
189+
self.apply()
190+
}
191+
162192
// 将更改保存到 plist
163193
func apply() {
164194
// 只有在有修改的情况下才进行保存
@@ -176,4 +206,5 @@ class PlistManagerUtils {
176206
isDirty = false
177207
}
178208
}
209+
179210
}

Resources/en.lproj/Localizable.strings

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
"Respring_text" = "Respring";
66
"Settings_text" = "Settings";
77
"Done_text" = "Done";
8+
"Action_Alert" = "Are you sure you want to %@?";
9+
"Confirm_text" = "Confirm";
810
"Cancel_text" = "Cancel";
911
"General_text" = "General";
1012
"Timer_text" = "Timer";

Resources/zh-Hans.lproj/Localizable.strings

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
"Respring_text" = "注销";
66
"Settings_text" = "设置";
77
"Done_text" = "完成";
8+
"Action_Alert" = "确定%@?";
9+
"Confirm_text" = "确定";
810
"Cancel_text" = "取消";
911
"General_text" = "通用";
1012
"Timer_text" = "倒计时器";

RootViewController.swift

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import UIKit
22

33
class RootViewController: UIViewController {
44

5+
private let settingsUtils = SettingsUtils.instance
6+
private let checkPermissionLabel = UILabel()
7+
private let respringButton = UIButton(type: .system)
8+
59
override func viewDidLoad() {
610
super.viewDidLoad()
711

@@ -30,9 +34,9 @@ class RootViewController: UIViewController {
3034
iconImageView.contentMode = .scaleAspectFit
3135

3236
// 检查权限
33-
let checkPermissionLabel = UILabel()
3437
checkPermissionLabel.translatesAutoresizingMaskIntoConstraints = false
3538
checkPermissionLabel.textAlignment = .center // 设置文本居中
39+
checkPermissionLabel.isHidden = !settingsUtils.getShowRootText()
3640

3741
let enable = self.checkInstallPermission()
3842

@@ -64,11 +68,11 @@ class RootViewController: UIViewController {
6468
rebootButton.isEnabled = enable // 无权限的时候不允许点击
6569

6670
// Respring
67-
let respringButton = UIButton(type: .system)
6871
respringButton.setTitle(NSLocalizedString("Respring_text", comment: ""), for: .normal)
6972
respringButton.translatesAutoresizingMaskIntoConstraints = false
7073
respringButton.addTarget(self, action: #selector(onClickRespringButton), for: .touchUpInside)
7174
respringButton.isEnabled = enable // 无权限的时候不允许点击
75+
respringButton.isHidden = !settingsUtils.getEnableRespringFunction()
7276

7377
// 添加设置项
7478
let settingsButton = UIButton(type: .system)
@@ -118,6 +122,7 @@ class RootViewController: UIViewController {
118122
settingsButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 50), // 左侧边距
119123
settingsButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -50) // 右侧边距
120124
])
125+
121126
}
122127

123128
func checkInstallPermission() -> Bool {
@@ -127,17 +132,71 @@ class RootViewController: UIViewController {
127132
}
128133

129134
@objc func onClickRebootButton() {
130-
let deviceController = DeviceController()
131-
deviceController.rebootDevice()
135+
136+
if settingsUtils.getShowAlertBeforeAction() {
137+
// 创建 UIAlertController
138+
let alertController = UIAlertController(title: nil, message: String.localizedStringWithFormat(NSLocalizedString("Action_Alert", comment: ""), NSLocalizedString("Reboot_Device_text", comment: "")), preferredStyle: .alert)
139+
140+
// 创建 "确定" 按钮(红色)
141+
let confirmAction = UIAlertAction(title: NSLocalizedString("Confirm_text", comment: ""), style: .destructive) { _ in
142+
let deviceController = DeviceController()
143+
deviceController.rebootDevice()
144+
}
145+
146+
// 创建 "取消" 按钮
147+
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel_text", comment: ""), style: .cancel) { _ in
148+
//
149+
}
150+
151+
// 添加按钮到 UIAlertController
152+
alertController.addAction(confirmAction)
153+
alertController.addAction(cancelAction)
154+
155+
// 显示弹窗
156+
self.present(alertController, animated: true, completion: nil)
157+
} else {
158+
let deviceController = DeviceController()
159+
deviceController.rebootDevice()
160+
}
161+
132162
}
133163

134164
@objc func onClickRespringButton() {
135-
let deviceController = DeviceController()
136-
deviceController.respring()
165+
166+
if settingsUtils.getShowAlertBeforeAction() {
167+
// 创建 UIAlertController
168+
let alertController = UIAlertController(title: nil, message: String.localizedStringWithFormat(NSLocalizedString("Action_Alert", comment: ""), NSLocalizedString("Respring_text", comment: "")), preferredStyle: .alert)
169+
170+
// 创建 "确定" 按钮(红色)
171+
let confirmAction = UIAlertAction(title: NSLocalizedString("Confirm_text", comment: ""), style: .destructive) { _ in
172+
let deviceController = DeviceController()
173+
deviceController.respring()
174+
}
175+
176+
// 创建 "取消" 按钮
177+
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel_text", comment: ""), style: .cancel) { _ in
178+
//
179+
}
180+
181+
// 添加按钮到 UIAlertController
182+
alertController.addAction(confirmAction)
183+
alertController.addAction(cancelAction)
184+
185+
// 显示弹窗
186+
self.present(alertController, animated: true, completion: nil)
187+
} else {
188+
let deviceController = DeviceController()
189+
deviceController.respring()
190+
}
191+
137192
}
138193

139194
@objc func onClickSettingsButton() {
140195
let settingsViewController = SettingsViewController()
196+
// 注册监听器
197+
settingsViewController.onSettingsChanged = { [weak self] in
198+
self?.updateUI()
199+
}
141200
// 嵌入到导航控制器
142201
let navController = UINavigationController(rootViewController: settingsViewController)
143202
// 设置导航栏完成按钮
@@ -156,6 +215,11 @@ class RootViewController: UIViewController {
156215
// 关闭模态视图
157216
dismiss(animated: true, completion: nil)
158217
}
218+
219+
private func updateUI() { // 因为设置更改 更新界面
220+
checkPermissionLabel.isHidden = !settingsUtils.getShowRootText()
221+
respringButton.isHidden = !settingsUtils.getEnableRespringFunction()
222+
}
159223
}
160224

161225
extension UIColor {

0 commit comments

Comments
 (0)