SwiftUI中的键盘快捷键、初始页面控制及网络权限管理解析
大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!
文章目录
- SwiftUI 中的键盘快捷键
- 控制 SwiftUI 应用的第一个界面
- NetworkManager & AuthManager:为什么会报“private 初始化器不可访问”
SwiftUI 中的键盘快捷键
你有没有用过 Mac 应用时想过——“要是这个功能能用快捷键直接触发就好了,不用每次都点按钮”?
SwiftUI 里面,这个功能超级容易加,用 .keyboardShortcut()
就行。
基本格式是这样的:
.keyboardShortcut("键", modifiers: [.command, .shift])
比如,你想用 Command + C 来触发一个动作,只要这样写:
Button("点击我") {print("按钮被点了!")
}
.keyboardShortcut("C", modifiers: [.command])
按下 Command + C,这个按钮的代码就会执行。
痛点分析:
假设你做的是一个 macOS 录音管理软件,用户一天可能要导出几十次音频文件。
如果每次都得用鼠标点击“导出”按钮,效率很低,还容易点错。
加一个快捷键(比如 Command + E 导出),直接秒操作,用户体验瞬间提升。
额外示例:多个快捷键支持同一操作
struct ContentView: View {var body: some View {Button("保存文件") {print("文件已保存")}.keyboardShortcut("S", modifiers: [.command]).keyboardShortcut(.return, modifiers: [.command]) // Command + 回车}
}
这里用户既能用 Command + S 保存,也能用 Command + 回车 保存,非常灵活。
控制 SwiftUI 应用的第一个界面
当你的应用启动时,你通常不想每次都显示同一个页面,而是要根据情况来决定显示什么。
比如用户已经登录了,那就直接进主界面;没登录,就去登录页。
基础写法:
@main
struct MyApp: App {@State private var isLoggedIn = falsevar body: some Scene {WindowGroup {if isLoggedIn {MainView()} else {LoginView()}}}
}
痛点分析:
想象一下你用银行 App,刚刚登录过,五分钟后回来,结果它又让你重新输账号密码。
是不是很烦?
通过控制初始界面,你可以让用户直接回到之前的状态,减少重复登录的麻烦。
额外示例:结合 UserDefaults 自动记住登录状态
@main
struct MyApp: App {@State private var isLoggedIn = UserDefaults.standard.bool(forKey: "isLoggedIn")var body: some Scene {WindowGroup {if isLoggedIn {MainView()} else {LoginView(onLoginSuccess: {UserDefaults.standard.set(true, forKey: "isLoggedIn")isLoggedIn = true})}}}
}
这样只要用户登录成功一次,下次启动 App 就会直接进主界面。
NetworkManager & AuthManager:为什么会报“private 初始化器不可访问”
你的 NetworkManager
是用 单例模式 写的:
class NetworkManager {static let shared = NetworkManager()private init() {}
}
这样做的意思是:
“外部禁止用
NetworkManager()
创建对象,只能用我提供的shared
共享实例。”
但是在 AuthManager
里面,你写了:
private let networkManager = NetworkManager() // 报错
这就违反了规则,所以 Swift 提示 “initializer is inaccessible due to ‘private’ protection level”。
正确做法:
private let networkManager = NetworkManager.shared
这样你用的就是那个唯一的共享实例。
痛点分析:
如果你不小心创建了多个 NetworkManager
实例,每个实例的 URLSession
和认证状态可能不一样,
结果可能出现:
- 登录成功,但上传文件时另一个实例不知道你已经登录。
- API 请求丢失了认证头,导致无缘无故失败。
这些都是很隐蔽、让人抓狂的 Bug。
额外示例:一个带 Token 的 NetworkManager
class NetworkManager {static let shared = NetworkManager()private var authToken: String?private init() {}func setToken(_ token: String) {self.authToken = token}func getRequest(url: String) async throws -> Data {var request = URLRequest(url: URL(string: url)!)if let token = authToken {request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")}let (data, _) = try await URLSession.shared.data(for: request)return data}
}
然后在 AuthManager
登录后:
let response = try await networkManager.login(email: "a@b.com", password: "123456")
NetworkManager.shared.setToken(response.token)
这样后续所有 API 调用都会自动带上 Token。