punchnet-macos/punchnet/Networking/SDLAPIClient.swift

83 lines
2.5 KiB
Swift

//
// SDLApi.swift
// sdlan
//
// Created by on 2024/6/5.
//
import Foundation
struct SDLAPIResponse<T: Decodable>: 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<T: Decodable>(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<T>.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)
}
}