// // SDLApi.swift // sdlan // // Created by 安礼成 on 2024/6/5. // import Foundation struct SDLAPIResponse: Decodable { let code: Int let message: String? let data: T? } struct SDLAPIError: Error, Decodable { let code: Int let message: String } struct SDLAPIClient { static var baseUrl: String { return "https://\(SystemConfig.serverHost)/api" } static private let token: String = "H6p*2RfEu4ITcL" // 基础参数信息 static let baseParams: [String: Any] = [ "client_id": SystemConfig.getClientId(), "mac": SystemConfig.macAddressString(mac: SystemConfig.getMacAddress()) ] static func doPost(path: String, params: [String: Any], as: T.Type) async throws -> T { let postData = try! JSONSerialization.data(withJSONObject: params) var request = URLRequest(url: URL(string: baseUrl + path)!) request.httpMethod = "POST" request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue(sign(params: params), forHTTPHeaderField: "X-sign") request.httpBody = postData let (data, _) = try await URLSession.shared.data(for: request) if let response = String(bytes: data, encoding: .utf8) { NSLog("url: \(path), response is: \(response)") } let apiResponse = try JSONDecoder().decode(SDLAPIResponse.self, from: data) // code = 0 表示成功 if apiResponse.code == 0 { if let data = apiResponse.data { return data } else if let data = apiResponse.message as? T { return data } else { throw SDLAPIError(code: 0, message: "数据格式错误") } } else if let message = apiResponse.message { throw SDLAPIError(code: apiResponse.code, message: message) } else { throw DecodingError.dataCorrupted( .init( codingPath: [], debugDescription: "Invalid JSON-RPC response: \(String(data: data, encoding: .utf8) ?? "")" ) ) } } private static func sign(params: [String: Any]) -> String { let keys = params.keys.sorted() let qs = keys.map { key in let str = String(describing: params[key] ?? "") return "\(key)=\(str)" }.joined(separator: "&") return SDLUtil.hmacMD5(key: token, data: qs) } }