一、IOS
1.下载导入SDK
下载 Proxy.framework.zip,解压后,将文件夹放到项目文件,Embed 设置为 Embed & sign,最小版本为ios 15.6
增加头文件,文件名随意,
Objective-C Bridging Header -> Header.h
主要是 #import <Proxy/Proxy.h>
#ifndef Header_h
#define Header_h
#import <Proxy/Proxy.h>
#endif /* Header_h */
2.初始化
1. 在AppDelegate.swift文件中通过initWith初始化
2025.1.24 新增 initWith内置了网络权限检查
2025.2.11 新增sdk内部的一个message弹出
import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(
_: UIApplication,
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// 使用 Task 调用异步方法
Task {
await WaylProxy.initWith(self)
}
return true
}
}
import SwiftUI
@main
struct App: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
2. 或者在入口文件
因为sdk需要向服务器发送请求,所以要在app有网络访问权限后再调用初始化sdk
import SwiftUI
@main
struct App: App {
// 如果不想使用UIApplicationDelegateAdaptor,请用 Proxy.shared.initial()
// 不要在init中调用 Proxy.shared.initial() 会阻塞进程
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
Task {
await WaylProxy.shared.initial()
}
}
}
}
}
3. 在info.plist文件添加uuid
<?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.wayl.proxy.UUID</key>
<string>****************</string>
</dict>
</plist>
3.功能使用
启动代理,传入需要的端口号,启动成功以后将监听该本地端口的所有请求
let proxy = WaylProxy.shared
let result = proxy.start(port: 10808)
也可以调用该方法先拿到一个空闲端口
getFreePorts()
停止代理服务
stop()
清除代理服务,该方法会清除掉所有的代理数据,(清理以后,是无法再次调用启动方法,需要初始化重新开启)
clear()
4.接口文档
@objcMembers public class Result : NSObject {
public let success: Bool
public let data: [String : Any]?
public let message: String?
public init(success: Bool, data: [String : Any]?, message: String?)
}
@objc public class WaylProxy : NSObject {
/// 单例对象,用于访问 WaylProxy
@objc public static let shared: Proxy.WaylProxy
/// 代理(监听器)对象,用于接收状态更新回调
@objc weak public var delegate: (any Proxy.WaylProxyDelegate)?
/// 对外只读 初始化状态
public var initiated: Bool { get }
/// 对外只读 套餐验证状态
public var isValidated: Bool { get }
/// 对外只读 代理开启状态
public var isStarted: Bool { get }
/// 初始化方法
/// - Parameter delegate: 初始化所需的代理对象,通常用于设置上下文环境。
/// - Note: 此方法是异步方法,调用时需要使用 `await`。已经内置网络权限检查(NWPathMonitor)
@objc public class func initWith(_ delegate: AnyObject) async
/// 启动本地代理服务
/// - Returns: `Result` 对象,包含初始化结果的状态、数据和消息。
/// - Note: 此方法是异步方法,调用时需要使用 `await`。
/// - 注意事项:
/// - 确保 `info.plist` 文件中已正确配置 `com.wayl.proxy.UUID`。
/// - 避免重复调用此方法,重复调用将被阻止。
/// - 调用前确保已经获取网络请求权限
@discardableResult
@objc public func initial() async -> Proxy.Result
/// 启动代理服务
/// - Parameter port: 要启动代理服务的端口号(范围为 `0-65535`)。
/// - Returns: `Result` 对象,包含启动结果的状态、数据和消息。
/// - 注意事项:
/// - 确保代理已完成初始化 (`initial` 方法)。
/// - 确保提供的端口号合法且未被占用。
@objc public func start(port: Int) -> Proxy.Result
/// 停止代理服务
/// - 注意: 调用此方法后,代理服务将停止运行,所有连接将断开。
@objc public func stop()
/// 获取可用端口
/// - Returns: `Result` 对象,包含成功与否状态以及一个可用的端口号。
/// - 注意: 可用于动态分配代理服务的端口。
@objc public func getFreePorts() -> Proxy.Result
/// 清理代理状态
/// - 注意: 此方法会清空代理相关的本地缓存,并停止正在运行的代理服务。
@objc public func clear()
}
@objc public protocol WaylProxyDelegate {
/// 当安装状态发生变化时回调
@objc func waylProxyDidUpdateInitialStatus(_ initiated: Bool)
/// 当验证状态发生变化时回调
@objc func waylProxyDidUpdateValidationStatus(_ isValidated: Bool)
/// 当代理服务启动状态发生变化时回调
@objc func waylProxyDidUpdateStartStatus(_ isStarted: Bool)
}
5.监听器
一个状态监听的简单例子
import SwiftUI
struct ContentView: View {
@StateObject private var delegate = ProxyDelegate() // 创建 ProxyDelegate 实例
@State private var logMessage = ""
var body: some View {
VStack(spacing: 20) {
if delegate.isInitializing {
ProgressView("正在初始化...")
.progressViewStyle(CircularProgressViewStyle())
} else {
Button(action: {
toggle()
}) {
Text(delegate.isRunning ? "停止" : "开启")
.foregroundColor(.white)
.padding()
.frame(maxWidth: .infinity)
.background(delegate.isRunning ? Color.red : Color.green)
.cornerRadius(10)
}
.disabled(delegate.isInitializing || !delegate.isValidated) // 初始化未完成或未验证通过时禁用按钮
}
// 显示状态信息
VStack(spacing: 10) {
HStack {
Text("初始化状态:")
.bold()
Text(delegate.isInitializing ? "进行中" : "完成")
.foregroundColor(delegate.isInitializing ? .orange : .green)
}
HStack {
Text("验证状态:")
.bold()
Text(delegate.isValidated ? "通过" : "未通过")
.foregroundColor(delegate.isValidated ? .green : .red)
}
HStack {
Text("代理状态:")
.bold()
Text(delegate.isRunning ? "已开启" : "已关闭")
.foregroundColor(delegate.isRunning ? .green : .red)
}
}
.padding()
.background(Color(UIColor.secondarySystemBackground))
.cornerRadius(10)
Text(logMessage)
.padding()
.foregroundColor(.gray)
.multilineTextAlignment(.center)
}
.padding()
.onAppear {
initializeProxy()
}
}
/// 初始化 WaylProxy
func initializeProxy() {
// 设置代理
WaylProxy.shared.delegate = delegate
Task {
// 调用异步初始化方法
await WaylProxy.shared.initial()
DispatchQueue.main.async {
delegate.isInitializing = false // 初始化完成
}
}
}
/// 启动或停止
func toggle() {
let proxy = WaylProxy.shared
if delegate.isRunning {
proxy.stop()
logMessage = "已停止"
delegate.isRunning = false
} else {
DispatchQueue.global(qos: .background).async {
let result = proxy.start(port: 10808)
DispatchQueue.main.async {
if result.success {
logMessage = "启动成功,端口: 10808"
delegate.isRunning = true
} else {
logMessage = result.message ?? "启动失败"
delegate.isRunning = false
}
}
}
}
}
}
class ProxyDelegate: NSObject, WaylProxyDelegate, ObservableObject {
@Published var isInitializing: Bool = true
@Published var isValidated: Bool = false
@Published var isRunning: Bool = false
func waylProxyDidUpdateInitialStatus(_ initiated: Bool) {
DispatchQueue.main.async {
self.isInitializing = !initiated
}
}
func waylProxyDidUpdateValidationStatus(_ isValidated: Bool) {
DispatchQueue.main.async {
self.isValidated = isValidated
}
}
func waylProxyDidUpdateStartStatus(_ isStarted: Bool) {
DispatchQueue.main.async {
self.isRunning = isStarted
}
}
}