我在后端使用 Stripe API 来处理付款。 这是 API URL:http://localhost:2000/charge/new
我正在为我的 iOS 应用程序使用 SwiftUI 来向我的 API 发送 POST 请求。
这是我的 DTO 对象:
DTO:
struct ChargeObjectDTO : Codable{
let vendorCustomerID: String;
let currency: String;
let chargeValue: CLongDouble;
let confirmationStatus: Bool;
}
这是我的请求逻辑,我正在尝试以 ChargeObjectDTO 作为对象发送 POST 请求:
支付API:
func createChargeRequest(chargeObj: ChargeObjectDTO) throws {
var url = “http://localhost:2000/charge/new"
do{
//send request
guard let myReqURL = URL(string: url) else { throw NetworkResponse.error };
//Request
var request = URLRequest(url: myReqURL);
request.httpMethod = "POST";
request.httpBody = try? JSONSerialization.data(withJSONObject: chargeObj);
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("token", forHTTPHeaderField: "Authorization") //Here is where we add tokens, like authentication tokens
URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200,
let myData = data,
let myJson = try? JSONSerialization.data(withJSONObject: data!, options: []) else{
let message = error?.localizedDescription ?? "Failed to Decode Response from Server"
print(message)
return
}
print("Created Payment Intent");
//DispatchQueue.main.async
}).resume();
}catch{
print(error)
}
}
这是 UI 屏幕 预订酒店:
struct HotelBookingScreen: View {
@State var myPaymentsAPI: PaymentsAPI = PaymentsAPI.init(chargeObjectDTO: ChargeObjectDTO(vendorCustomerID: "", currency: "", chargeValue: 0, confirmationStatus: false));
var body: some View {
Button(action: {
try? myPaymentsAPI.createChargeRequest(chargeObj: ChargeObjectDTO(vendorCustomerID: "cus_12345”, currency: "USD", chargeValue: 100, confirmationStatus: true))
}, label: {
Text("Confirm")
.frame(maxWidth: 300)
});
}
}
问题是什么,为什么我会收到此错误,即使我正在解码 JSON 对象?
我收到的错误是:
由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“*** +[NSJSONSerialization dataWithJSONObject:options:error:]:JSON 写入中的顶级类型无效”
这是我解决问题的方法,希望对某人有帮助。
代码:
class PaymentsAPI: ObservableObject{
let paymentsAPI = URL.paymentsAPIURL;
var endpoint: String;
init(endpoint: String) {
self.endpoint = endpoint
}
func createChargeRequest(chargeObj: ChargeObjectDTO, completion: @escaping(Result<ChargeObjectDTO, NetworkResponse>) -> Void) {
//var myURL = "\(paymentsAPI)/charges/vendor/charge/new"
let myURL = "\(paymentsAPI)\(endpoint)"
do{
guard let reqURL = URL(string: myURL) else{ throw NetworkResponse.error }
//Request
var request = URLRequest(url: reqURL);
request.httpMethod = "POST";
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONEncoder().encode(chargeObj)
let dataTask = URLSession.shared.dataTask(with: request){ data, response, error in
guard let myHttpResponse = response as? HTTPURLResponse, myHttpResponse.statusCode == 200,
let jsonData = data else{
completion(.failure(NetworkResponse.error))
return
}
do{
let messageData = try JSONDecoder().decode(ChargeObjectDTO.self, from: jsonData)
completion(.success(messageData))
}catch{
completion(.failure(.error))
}
}
dataTask.resume()
}catch{
completion(.failure(.error))
}
}
}