Xcode11: 删除默认Main.storyBoard, 自定义UIWindow的变化 UIWindow 不能在AppDelegate中处理

Xcode11在iOS13中引入了Scene Delegate,导致App Delegate不再处理UI生命周期。根据WWDC2019官方文档,App Delegate现在仅负责App和新的Scene Session生命周期,而UI生命周期由Scene Delegate接手。因此,删除Main.storyBoard并在Info.plist中移除SceneDelegate的StoryboardName成为必要步骤。初始化UIWindow的方法也发生了变化,现在需在Scene Delegate中完成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Xcode自动新增了一个SceneDelegate文件,查找了一下官方文档WWDC2019:Optimizing App Launch 发现,iOS13中appdelegate的职责发现了改变: iOS13之前,Appdelegate的职责全权处理App生命周期和UI生命周期; iOS13之后,Appdelegate的职责是: 1、处理 App 生命周期 2、新的 Scene Session 生命周期 那UI的生命周期呢?交给新增的Scene Delegate处理, Appdelegate不在负责UI生命周期,所有UI生命周期交给SceneDelegate处理

除了与以前版本一样,要删除Main storyboard file base name之外, 还要在项目Info.plist中, 删除SceneDelegate的StoryboardName

初始化window方法需要改变: 现在不再在Appdelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions进行初始化, 而是在SceneDelegate中初始化了

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    UIWindowScene *windowScene = (UIWindowScene *)scene;
    self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
    self.window.backgroundColor = [UIColor purpleColor];
    UIViewController *VC = [[UIViewController alloc]init];
    UINavigationController *NVC = [[UINavigationController alloc]initWithRootViewController:VC];
    [self.window setRootViewController:NVC];
    [self.window makeKeyAndVisible];
}

 

 

import UIKit import SystemConfiguration class SecurityMonitorViewController: UIViewController { // MARK: - 安全状态监控 private var securityTimer: Timer? private let checkInterval: TimeInterval = 5.0 // 检测间隔(秒) override func viewDidLoad() { super.viewDidLoad() setupUI() startSecurityMonitoring() } // MARK: - 界面组件 private let statusLabel: UILabel = { let label = UILabel() label.textAlignment = .center label.numberOfLines = 0 label.translatesAutoresizingMaskIntoConstraints = false return label }() private let logTextView: UITextView = { let textView = UITextView() textView.isEditable = false textView.backgroundColor = .systemGray6 textView.translatesAutoresizingMaskIntoConstraints = false return textView }() // MARK: - UI设置 private func setupUI() { view.backgroundColor = .white view.addSubview(statusLabel) view.addSubview(logTextView) NSLayoutConstraint.activate([ statusLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20), statusLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), statusLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20), logTextView.topAnchor.constraint(equalTo: statusLabel.bottomAnchor, constant: 20), logTextView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), logTextView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20), logTextView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20) ]) } // MARK: - 安全监控 private func startSecurityMonitoring() { securityTimer = Timer.scheduledTimer(withTimeInterval: checkInterval, repeats: true) { [weak self] _ in self?.performSecurityChecks() } securityTimer?.fire() // 立即执行首次检测 } private func stopSecurityMonitoring() { securityTimer?.invalidate() securityTimer = nil } // MARK: - 安全检测方法 private func performSecurityChecks() { var securityStatus = "✅ 设备安全状态正常" var logMessages = [String]() // 1. 越狱检测 if isDeviceJailbroken() { securityStatus = "⚠️ 设备可能已越狱!" logMessages.append("检测到越狱迹象 - \(Date())") } // 2. 可疑文件检测 if checkForSuspiciousFiles() { securityStatus = "⚠️ 检测到可疑文件!" logMessages.append("检测到可疑系统文件 - \(Date())") } // 3. 调试器检测 if isDebuggerAttached() { securityStatus = "⚠️ 检测到调试器连接!" logMessages.append("检测到调试器连接 - \(Date())") } // 4. 端口检测 (简化的端口检查) if checkOpenPorts() { securityStatus = "⚠️ 检测到异常开放端口!" logMessages.append("检测到异常开放端口 - \(Date())") } // 更新UI DispatchQueue.main.async { self.statusLabel.text = securityStatus self.statusLabel.textColor = securityStatus.contains("⚠️") ? .red : .systemGreen // 添加日志 logMessages.forEach { message in self.logTextView.text += "\(message)\n" } // 自动滚动到底部 let range = NSRange(location: self.logTextView.text.count - 1, length: 1) self.logTextView.scrollRangeToVisible(range) } } // MARK: - 安全检测方法实现 /// 检测设备是否越狱 private func isDeviceJailbroken() -> Bool { // 检查常见越狱文件路径 let jailbreakPaths = [ "/Applications/Cydia.app", "/Library/MobileSubstrate/MobileSubstrate.dylib", "/bin/bash", "/usr/sbin/sshd", "/etc/apt", "/private/var/lib/apt" ] for path in jailbreakPaths { if FileManager.default.fileExists(atPath: path) { return true } } // 尝试写入系统目录 let stringToWrite = "Jailbreak Test" do { try stringToWrite.write(toFile: "/private/jailbreak.txt", atomically: true, encoding: .utf8) try? FileManager.default.removeItem(atPath: "/private/jailbreak.txt") return true } catch { // 写入失败说明未越狱 } return false } /// 检测可疑文件 private func checkForSuspiciousFiles() -> Bool { let suspiciousPaths = [ "/private/var/mobile/Library/Preferences/.mdm_config", "/private/var/mobile/Library/Caches/com.apple.mdm" ] return suspiciousPaths.contains { FileManager.default.fileExists(atPath: $0) } } /// 检测调试器连接 private func isDebuggerAttached() -> Bool { var info = kinfo_proc() var size = MemoryLayout<kinfo_proc>.size var mib: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()] sysctl(&mib, 4, &info, &size, nil, 0) return (info.kp_proc.p_flag & P_TRACED) != 0 } /// 简化的端口检测 private func checkOpenPorts() -> Bool { let portsToCheck: [Int32] = [22, 23, 5900] // SSH, Telnet, VNC for port in portsToCheck { let sock = socket(AF_INET, SOCK_STREAM, 0) guard sock >= 0 else { continue } var addr = sockaddr_in() addr.sin_family = sa_family_t(AF_INET) addr.sin_port = in_port_t(port).bigEndian addr.sin_addr.s_addr = inet_addr("127.0.0.1") let bindResult = withUnsafePointer(to: &addr) { $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { bind(sock, $0, socklen_t(MemoryLayout<sockaddr_in>.size)) } } close(sock) if bindResult == 0 { return true // 端口已开放 } } return false } // MARK: - 生命周期 override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) stopSecurityMonitoring() } deinit { stopSecurityMonitoring() } } // 在AppDelegate中启动监控 @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let window = UIWindow(frame: UIScreen.main.bounds) window.rootViewController = SecurityMonitorViewController() window.makeKeyAndVisible() return true } } 运行结果为Output: error:exit status 1 package main: main.go:1:1: expected 'package', found 'import'
最新发布
07-14
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值