You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS 26中基于Wi-Fi Aware的NetworkConnection实现HTTP通信的方法咨询

iOS 26中基于Wi-Fi Aware的NetworkConnection实现HTTP通信的方法咨询

嘿,这个问题我刚好琢磨过,咱们来一步步拆解怎么在iOS 26的Wi-Fi Aware NetworkConnection上跑HTTP通信——核心思路其实是把HTTP报文适配成NetworkConnection能处理的编码格式,因为默认的send方法是基于自定义应用层协议的,没法直接丢HTTP请求进去,得自己做一层适配。

一、先搞懂NetworkConnection.send的核心约束

你贴的这个send方法有几个关键限制得先明确:

  • 要发送的内容必须实现Encodable协议
  • 得用符合NetworkCoder的编码器来做编解码逻辑
  • 通信两端要统一用这套编码器,不然对方根本解析不了你的报文

所以咱们的核心工作就是写一个能处理HTTP报文的自定义NetworkCoder,再把HTTP请求封装成Encodable的对象。

二、实现自定义的HTTP NetworkCoder

首先咱们写一个NetworkCoder的实现,专门负责HTTP请求和响应的编解码:

struct HTTPNetworkCoder: NetworkCoder {
    typealias Input = HTTPRequest
    typealias Output = HTTPResponse

    func encode(_ value: HTTPRequest) throws -> Data {
        // 把HTTPRequest结构体拼接成标准HTTP请求报文
        var requestString = "\(value.method.rawValue) \(value.path) HTTP/1.1\r\n"
        requestString += "Host: \(value.host)\r\n"
        // 处理请求体相关的头部
        if let body = value.body {
            requestString += "Content-Length: \(body.count)\r\n"
            requestString += "Content-Type: application/json\r\n" // 可根据实际需求修改编码类型
        }
        requestString += "\r\n" // 报文头部和体的分隔符
        
        var requestData = requestString.data(using: .utf8)!
        if let body = value.body {
            requestData.append(body)
        }
        return requestData
    }

    func decode(_ data: Data) throws -> HTTPResponse {
        // 把收到的响应Data解析成HTTPResponse对象
        guard let responseString = String(data: data, encoding: .utf8) else {
            throw NSError(domain: "HTTPDecoder", code: -1, userInfo: [NSLocalizedDescriptionKey: "响应数据解析失败"])
        }
        // 简单拆分状态行、头部和响应体(实际项目要做更严谨的处理)
        let components = responseString.split(separator: "\r\n\r\n", maxSplits: 1)
        let headerSection = components[0]
        let bodySection = components.count > 1 ? components[1] : ""
        let statusLine = headerSection.split(separator: "\r\n")[0]
        let statusCode = Int(statusLine.split(separator: " ")[1]) ?? 500
        
        return HTTPResponse(statusCode: statusCode, body: bodySection.data(using: .utf8))
    }
}

// 配套的HTTP请求/响应结构体,实现Encodable/Decodable
enum HTTPMethod: String {
    case get = "GET"
    case post = "POST"
}

struct HTTPRequest: Encodable {
    let method: HTTPMethod
    let host: String
    let path: String
    let body: Data?
}

struct HTTPResponse: Decodable {
    let statusCode: Int
    let body: Data?
}

这个编码器的作用就是把咱们的HTTPRequest转换成标准的HTTP报文Data,再把收到的响应Data解析成易处理的HTTPResponse对象。

三、用NetworkConnection发送HTTP请求

接下来就是实际发送请求的步骤了:

  1. 确保你已经通过Wi-Fi Aware发现了目标端点,拿到了对应的NWEndpoint实例
  2. 用咱们的自定义编码器初始化NetworkConnection
  3. 构造HTTP请求对象,调用send方法发送

示例代码如下:

// 假设你已经通过Wi-Fi Aware发现流程拿到了目标端点
let targetEndpoint: NWEndpoint = ...
// 初始化NetworkConnection,指定用咱们的HTTP编码器
let connection = NetworkConnection<HTTPNetworkCoder>(endpoint: targetEndpoint)

// 构造一个GET请求
let getRequest = HTTPRequest(
    method: .get,
    host: "aware-endpoint", // 这里的Host可以是端点标识,点对点场景下也可以留空
    path: "/api/user/data",
    body: nil
)

// 发送请求并处理响应
do {
    let response = try await connection.send(getRequest)
    // 处理响应结果
    print("HTTP响应状态码: \(response.statusCode)")
    if let bodyData = response.body, let bodyString = String(data: bodyData, encoding: .utf8) {
        print("响应内容: \(bodyString)")
    }
} catch {
    print("请求发送失败: \(error.localizedDescription)")
}

四、要注意的几个坑

  • 端点兼容性:目标端点必须能识别标准HTTP报文,或者也用同样的HTTPNetworkCoder来解析,不然对方收到的就是一堆 raw Data,根本不知道是HTTP请求。
  • HTTP报文的严谨性:示例里的报文拼接是简化版,实际项目里要处理各种头部(比如ConnectionAccept)、编码格式(URL编码、表单编码等),还要处理重定向、分块响应等复杂情况。
  • 连接稳定性:Wi-Fi Aware的点对点连接可能会因为距离、环境干扰断开,要在catch块里做好重试、重连的逻辑。
  • 安全问题:如果需要加密通信(类似HTTPS),得在NetworkConnection的配置里添加TLS协议元数据,确保请求内容不会被窃听。

如果你有具体的场景需求(比如POST大文件、处理Cookie),咱们再细化讨论~

火山引擎 最新活动