Postman GET возвращает успешный результат, но приложение SwiftUI GET возвращает ошибку декодирования

Я использую паровой сервер. Все сетевые запросы моего приложения работают отлично, за исключением getOrders. При запуске запроса на Postman он возвращается успешно. Может ли кто-нибудь увидеть, что делает Почтальон, чтобы получить ответ, который я не могу сделать?

Это ошибка, которую я сейчас получаю:

typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "dateOrdered", intValue: nil)], debugDescription: "Expected to decode Double but found a string instead.", underlyingError: nil))

Вот мой код сетевого запроса:

func getOrders() async throws -> [Order] {
        
        let session = URLSession.shared
        var request = URLRequest(url: URL(string: "\(API.url)/orders/")!)
        
        request.httpMethod = "GET"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("Bearer \(token!.value)", forHTTPHeaderField: "Authorization")
            
            // Make the request
        let (data, response) = try await session.data(for: request)
        print(data)
        
        print(response)
            // Ensure we had a good response (status 200)
            guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
                throw GetOrdersError.unableToGetOrders
            }
        print(httpResponse.statusCode)
            
        let decoder = JSONDecoder()
        let orders = try decoder.decode([Order].self, from: data)
        
        print(orders)
        return orders
    }

Вот модель заказа в моем приложении:

struct Order: Identifiable, Codable {
    
    var id: UUID?
    var residentID: UUID
    var house: String
    var dateOrdered: Date
    var allPurposeCleaner: Bool
    var airFreshener: Bool
    var laundryPods: Bool
    var dishPods: Bool
    var dishSoap: Bool
    var windex: Bool
    var cloroxWipes: Bool
    var paperTowels: Bool
    var toiletPaper: Bool
    var toiletBowlCleaner: Bool
    var thrift: Bool
    var swifferPads: Bool
    var trashBags: Bool
    var isOrderCompleted: Bool
    
    static let houses = ["Wolf Pack", "Crow House", "Raptor House", "Lemur House", "Orca Pod", "Gorilla House", "Bison House", "Lion's Den"]
    
    
    init(id: UUID?, residentID: UUID, house: String, dateOrdered: Date, allPurposeCleaner: Bool, airFreshener: Bool, laundryPods: Bool, dishPods: Bool, dishSoap: Bool, windex: Bool, cloroxWipes: Bool, paperTowels: Bool, toiletPaper: Bool, toiletBowlCleaner: Bool, thrift: Bool, swifferPads: Bool, trashBags: Bool, isOrderCompleted: Bool) {
        
        self.id = id
        self.residentID = residentID
        self.house = house
        self.dateOrdered = dateOrdered
        self.allPurposeCleaner = allPurposeCleaner
        self.airFreshener = airFreshener
        self.laundryPods = laundryPods
        self.dishPods = dishPods
        self.dishSoap = dishSoap
        self.windex = windex
        self.cloroxWipes = cloroxWipes
        self.paperTowels = paperTowels
        self.toiletPaper = toiletPaper
        self.toiletBowlCleaner = toiletBowlCleaner
        self.thrift = thrift
        self.swifferPads = swifferPads
        self.trashBags = trashBags
        self.isOrderCompleted = isOrderCompleted
    }
}

Вот модель заказа на моем сервере:

import Foundation
import Vapor
import Fluent

final class Order: Model, Content {
    
    init() {
    }
    
    static var schema: String = "orders"
    
    init(id: UUID, residentID: UUID, house: String, dateOrdered: Date, allPurposeCleaner: Bool, airFreshener: Bool, laundryPods: Bool, dishPods: Bool, dishSoap: Bool, windex: Bool, cloroxWipes: Bool, paperTowels: Bool, toiletPaper: Bool, toiletBowlCleaner: Bool, thrift: Bool, swifferPads: Bool, trashBags: Bool, isOrderCompleted: Bool) {
            
        self.id = id
        self.residentID = residentID
        self.house = house
        self.dateOrdered = dateOrdered
        self.allPurposeCleaner = allPurposeCleaner
        self.airFreshener = airFreshener
        self.laundryPods = laundryPods
        self.dishPods = dishPods
        self.dishSoap = dishSoap
        self.windex = windex
        self.cloroxWipes = cloroxWipes
        self.paperTowels = paperTowels
        self.toiletPaper = toiletPaper
        self.toiletBowlCleaner = toiletBowlCleaner
        self.thrift = thrift
        self.swifferPads = swifferPads
        self.trashBags = trashBags
        self.isOrderCompleted = isOrderCompleted
    }
    
    @ID(key: .id)
    var id: UUID?
    
    @Field(key: "residentID")
    var residentID: UUID
    
    @Field(key: "house")
    var house: String
    
    @Field(key: "dateOrdered")
    var dateOrdered: Date
    
    @Field(key: "allPurposeCleaner")
    var allPurposeCleaner: Bool
    
    @Field(key: "airFreshener")
    var airFreshener: Bool
    
    @Field(key: "laundryPods")
    var laundryPods: Bool
    
    @Field(key: "dishPods")
    var dishPods: Bool
    
    @Field(key: "dishSoap")
    var dishSoap: Bool
    
    @Field(key: "windex")
    var windex: Bool
    
    @Field(key: "cloroxWipes")
    var cloroxWipes: Bool
    
    @Field(key: "paperTowels")
    var paperTowels: Bool
    
    @Field(key: "toiletPaper")
    var toiletPaper: Bool
    
    @Field(key: "toiletBowlCleaner")
    var toiletBowlCleaner: Bool
    
    @Field(key: "thrift")
    var thrift: Bool
    
    @Field(key: "swifferPads")
    var swifferPads: Bool
    
    @Field(key: "trashBags")
    var trashBags: Bool
    
    @Field(key: "isOrderCompleted")
    var isOrderCompleted: Bool
    
}

Вот Почтальон работает нормально:

Примечание. Apple требует подключения https. Чтобы использовать http, вам необходимо установить «NSAppTransportSecurity» в своем Info.plist, чтобы разрешить http подключение к серверу. Вы это сделали?

workingdog support Ukraine 14.04.2024 04:32

замените print(data) на print(String(data: data, encoding: .utf8)) и покажите нам, что вы получаете от сервера. Имеющиеся у вас модели должны соответствовать полученным вами данным в формате JSON. Вы можете попробовать создать dateOrdered строку и посмотреть, сработает ли это. Альтернативно используйте decoder.dateDecodingStrategy = ..., в зависимости от формата даты.

workingdog support Ukraine 14.04.2024 04:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
94
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

попробуйте этот подход, используя определенный декодер даты, отрегулируйте его, если ваши даты не iso8601:

  let decoder = JSONDecoder()
  decoder.dateDecodingStrategy = .iso8601  // <-- here
  let orders = try decoder.decode([Order].self, from: data)

Чтобы использовать свой собственный формат даты, используйте

decoder.dateDecodingStrategy = .formatted(myDateFormat)

Это действительно исправило ситуацию, спасибо!

AFinch 14.04.2024 06:11

Другие вопросы по теме