1
1
This commit is contained in:
@@ -2,20 +2,27 @@ import Foundation
|
||||
import Library
|
||||
import SwiftUI
|
||||
|
||||
|
||||
/// UUVPN iOS应用程序入口点
|
||||
/// 管理应用生命周期和视图路由,根据登录状态显示相应界面
|
||||
@main
|
||||
struct Application: App {
|
||||
/// 应用代理适配器
|
||||
@UIApplicationDelegateAdaptor private var appDelegate: ApplicationDelegate
|
||||
|
||||
/// VPN扩展环境管理
|
||||
@StateObject private var environments = ExtensionEnvironments()
|
||||
|
||||
/// 用户登录状态
|
||||
@State private var isLoggedIn = UserManager.shared.isUserLoggedIn()
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
// 根据登录状态显示界面
|
||||
if isLoggedIn {
|
||||
//MainView().environmentObject(environments)
|
||||
// 已登录:显示主界面
|
||||
HomeView(isLoggedIn: $isLoggedIn).environmentObject(environments)
|
||||
}else{
|
||||
} else {
|
||||
// 未登录:显示登录界面
|
||||
LoginContentView(isLoggedIn: $isLoggedIn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,36 +5,50 @@ import Library
|
||||
import Network
|
||||
import UIKit
|
||||
|
||||
/// UUVPN应用代理
|
||||
/// 管理应用生命周期、后台任务和VPN配置
|
||||
class ApplicationDelegate: NSObject, UIApplicationDelegate {
|
||||
/// 配置文件服务器(仅iOS 16+)
|
||||
private var profileServer: ProfileServer?
|
||||
|
||||
/// 应用启动完成处理
|
||||
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
||||
|
||||
// 初始化Libbox VPN框架
|
||||
LibboxSetup(FilePath.sharedDirectory.relativePath, FilePath.workingDirectory.relativePath, FilePath.cacheDirectory.relativePath, false)
|
||||
setup()
|
||||
return true
|
||||
}
|
||||
|
||||
/// 配置后台服务
|
||||
private func setup() {
|
||||
do {
|
||||
// 配置后台配置文件更新任务
|
||||
try UIProfileUpdateTask.configure()
|
||||
NSLog("setup background task success")
|
||||
} catch {
|
||||
NSLog("setup background task error: \(error.localizedDescription)")
|
||||
}
|
||||
|
||||
// 执行异步设置任务
|
||||
Task {
|
||||
if UIDevice.current.userInterfaceIdiom == .phone {
|
||||
// 为iPhone设备请求网络权限
|
||||
await requestNetworkPermission()
|
||||
}
|
||||
// 初始化后台配置文件服务器
|
||||
await setupBackground()
|
||||
}
|
||||
}
|
||||
|
||||
/// 设置后台配置文件服务器(仅iOS 16+)
|
||||
private nonisolated func setupBackground() async {
|
||||
|
||||
if #available(iOS 16.0, *) {
|
||||
do {
|
||||
let profileServer = try ProfileServer()
|
||||
profileServer.start()
|
||||
|
||||
// 在主线程更新配置文件服务器引用
|
||||
await MainActor.run {
|
||||
self.profileServer = profileServer
|
||||
}
|
||||
@@ -45,22 +59,23 @@ class ApplicationDelegate: NSObject, UIApplicationDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
private nonisolated func requestNetworkPermission() async {
|
||||
if await SharedPreferences.networkPermissionRequested.get() {
|
||||
return
|
||||
}
|
||||
if !DeviceCensorship.isChinaDevice() {
|
||||
await SharedPreferences.networkPermissionRequested.set(true)
|
||||
return
|
||||
}
|
||||
URLSession.shared.dataTask(with: URL(string: "http://captive.apple.com")!) { _, response, _ in
|
||||
if let response = response as? HTTPURLResponse {
|
||||
if response.statusCode == 200 {
|
||||
Task {
|
||||
await SharedPreferences.networkPermissionRequested.set(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.resume()
|
||||
}
|
||||
}
|
||||
/// 为中国设备请求网络权限
|
||||
private nonisolated func requestNetworkPermission() async {
|
||||
if await SharedPreferences.networkPermissionRequested.get() {
|
||||
return
|
||||
}
|
||||
if !DeviceCensorship.isChinaDevice() {
|
||||
await SharedPreferences.networkPermissionRequested.set(true)
|
||||
return
|
||||
}
|
||||
URLSession.shared.dataTask(with: URL(string: "http://captive.apple.com")!) { _, response, _ in
|
||||
if let response = response as? HTTPURLResponse {
|
||||
if response.statusCode == 200 {
|
||||
Task {
|
||||
await SharedPreferences.networkPermissionRequested.set(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.resume()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import Foundation
|
||||
import Foundation
|
||||
|
||||
|
||||
// 创建一个全局的 UserManager 类,负责从 UserDefaults 中读取和存储用户信息及登录状态
|
||||
class UserManager {
|
||||
static let shared = UserManager()
|
||||
|
||||
@@ -26,7 +25,7 @@ class UserManager {
|
||||
private let baseURLKey = "baseURLKey"
|
||||
private let crisptoken = "crisptoken"
|
||||
|
||||
// UserDefaults 引用
|
||||
/// UserDefaults实例
|
||||
private let defaults = UserDefaults.standard
|
||||
|
||||
|
||||
@@ -65,7 +64,7 @@ class UserManager {
|
||||
defaults.synchronize()
|
||||
}
|
||||
|
||||
//存储 URL 相关信息
|
||||
/// 存储基础URL
|
||||
func storebaseURLData(data: String) {
|
||||
defaults.set(data, forKey: "baseURLKey")
|
||||
defaults.synchronize()
|
||||
@@ -102,7 +101,7 @@ class UserManager {
|
||||
|
||||
|
||||
|
||||
// 更新登录状态
|
||||
/// 更新登录状态
|
||||
func updateLoginStatus(_ loggedIn: Bool) {
|
||||
defaults.set(loggedIn, forKey: loginStatusKey)
|
||||
defaults.synchronize()
|
||||
@@ -118,48 +117,48 @@ class UserManager {
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否已登录
|
||||
/// 检查登录状态
|
||||
func isUserLoggedIn() -> Bool {
|
||||
return defaults.bool(forKey: loginStatusKey)
|
||||
}
|
||||
|
||||
// 存储用户信息
|
||||
/// 存储用户信息
|
||||
func storeUserInfo(email: String, avator: String) {
|
||||
defaults.set(email, forKey: userEmailKey)
|
||||
defaults.set(avator, forKey: avatarurlKey) // 假设 info 是 JSON 字符串
|
||||
defaults.set(avator, forKey: avatarurlKey)
|
||||
defaults.synchronize()
|
||||
}
|
||||
|
||||
// 读取用户信息
|
||||
/// 获取用户信息
|
||||
func getUserInfo() -> (email: String, avator: String) {
|
||||
let email = defaults.string(forKey: userEmailKey) ?? ""
|
||||
let avator = defaults.string(forKey: avatarurlKey) ?? ""
|
||||
return (email, avator)
|
||||
}
|
||||
|
||||
// 存储 autodata
|
||||
/// 存储认证数据
|
||||
func storeAutoData(data: String) {
|
||||
defaults.set(data, forKey: autodataKey)
|
||||
defaults.synchronize()
|
||||
}
|
||||
|
||||
// 读取 autodata
|
||||
/// 获取订阅URL数据
|
||||
func getSuburlData() -> String {
|
||||
return defaults.string(forKey: subURLDataKey) ?? ""
|
||||
}
|
||||
|
||||
// 存储 autodata
|
||||
/// 存储订阅URL数据
|
||||
func storeSuburlData(data: String) {
|
||||
defaults.set(data, forKey: subURLDataKey)
|
||||
defaults.synchronize()
|
||||
}
|
||||
|
||||
// 读取 autodata
|
||||
/// 获取认证数据
|
||||
func getAutoData() -> String {
|
||||
return defaults.string(forKey: autodataKey) ?? ""
|
||||
}
|
||||
|
||||
// 清除所有数据(例如在登出时)
|
||||
/// 清除用户数据
|
||||
func clearUserData() {
|
||||
defaults.removeObject(forKey: loginStatusKey)
|
||||
defaults.removeObject(forKey: userEmailKey)
|
||||
|
||||
@@ -11,7 +11,7 @@ import Crisp
|
||||
|
||||
struct SupportView: View {
|
||||
|
||||
@Environment(\.presentationMode) var presentationMode // 环境变量用于控制视图的呈现
|
||||
@Environment(\.presentationMode) var presentationMode
|
||||
|
||||
var body: some View {
|
||||
NavigationView(content: {
|
||||
@@ -21,7 +21,7 @@ struct SupportView: View {
|
||||
HStack{
|
||||
Button(action: {
|
||||
|
||||
presentationMode.wrappedValue.dismiss() // 手动触发返回
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
}, label: {
|
||||
|
||||
Image(systemName: "chevron.left")
|
||||
@@ -29,7 +29,7 @@ struct SupportView: View {
|
||||
|
||||
Text("返回")
|
||||
.foregroundColor(.white)
|
||||
}).padding(10) // 增加可点击区域
|
||||
}).padding(10)
|
||||
|
||||
Spacer(minLength: 0)
|
||||
|
||||
@@ -59,7 +59,7 @@ struct SupportView: View {
|
||||
})
|
||||
|
||||
.navigationBarHidden(true)
|
||||
.navigationBarBackButtonHidden(true) // 隐藏返回按钮
|
||||
.navigationBarBackButtonHidden(true)
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user