Administrator
发布于 2025-03-07 / 2 阅读

SDK ios集成文档

一、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
        }
    }
}