Я пытаюсь получить данные через серверный API и получаю данные по функции запроса в сетевом классе, например
if let getData = data{
result = .success(getData)
let respondString = String(data:getData, encoding: .utf8) ?? "could not convert our data into string"
// print("backend response is \(respondString)") //here i'm getting data perfeclty
}
но я не знаю, почему данные не декодируются идеально, когда я вызываю сетевые вызовы в домашнем контроллере для загрузки данных, они не работают нормально. Я приложил все скриншоты как а также код сетевого класса, пожалуйста, помогите решить эту проблему.
NETWORKING CALSS:
struct NetworkService{
static let shared = NetworkService()
private init(){
}
func fetchAllCategories(completion: @escaping(Result)-> Void){
request(route: .fetchAllCategories, method: .get, completion: completion)
}
// 1.private function access in this struct not outsude the struct
private func createRequest(route: Route, method: Method, parameters : [String:Any]? = nil) -> URLRequest?
{
//baseUrl = "https://yummie.glitch.me/temp"
let urlString1 = Route.baseUrl + route.description //calling from route class
guard let url = URL(string: urlString1) else { return nil }//convet url into string
var urlRequest = URLRequest(url: url)
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
//rawvlaue return cases as a string
urlRequest.httpMethod = method.rawValue
if let params = parameters{
switch method{
case .get:
// https:// google.com/books?type=cartoon&page=1
var urlComponent = URLComponents(string: urlString1)
urlComponent?.queryItems = params.map {
URLQueryItem(name: $0, value: "\($1)")}
urlRequest.url = urlComponent?.url
case .post, .delete, .patch:
let bodyData = try? JSONSerialization.data(withJSONObject: params, options: [])
urlRequest.httpBody = bodyData
}
}
return urlRequest
}
//2. Create One Generic Function to Make Different Types of API Requests
private func request(route: Route,method: Method, parameters: [String: Any]? = nil, completion: @escaping(Result) -> Void){
guard let request = createRequest(route: route, method: method, parameters: parameters) else {//caling 1st function
completion(.failure(AppError.unknownError)) //calling error that define in APPErro class
return
}
URLSession.shared.dataTask(with: request){ (data, response, error) in
var result: Result?
if let getData = data{
result = .success(getData)
let respondString = String(data:getData, encoding: .utf8) ?? "could not convert our data into string"
// print("backend response is \(respondString)") //here i'm getting data perfeclty
}
else if let error = error{
result = .failure(error)
print("error is:\(error.localizedDescription)")
}
DispatchQueue.main.async {
print("success \(result)")
self.handleRequest(result: result , completion: completion)
}
}.resume()
}
//4.hnalde the api response from api response class and show to decoadlbe data that shows on api
private func handleRequest(result:Result?, completion: @escaping(Result) -> Void){
guard let result = result else {
completion(.failure(AppError.unknownError))
return
}
switch result {
case .success(let data):
let decoder = JSONDecoder()
guard let response = try? decoder.decode(ApiResponse.self, from: data) else {
completion(.failure(AppError.errorDecoding))
return
}
if let error = response.error{
completion(.failure(AppError.ServerError(error)))
}
if let decodedData = response.data{
completion(.success(decodedData))
}else{
completion(.failure(AppError.unknownError))
}
case .failure(let error):
completion(.failure(error))
}
}
}
КЛАСС ДОМАШНЕГО КОНТРОЛЛЕРА:
class HomeController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var categories: [String] = ["Food Category","Popular Dishes","Chief Specials"]
var categoresdish: [DishCategory] = []{
didSet{
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
var popular: [Dish] = []{
didSet{
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
var specials: [Dish] = []{
didSet{
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.loadData()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.register(UINib(nibName: String(describing: HomeTableViewCell.self), bundle: .main), forCellReuseIdentifier: String(describing: HomeTableViewCell.self))
}
private func loadData(){
ProgressHUD.show()
NetworkService.shared.fetchAllCategories { [weak self] (result) in
switch result{
case .success(let allDishes):
ProgressHUD.dismiss()
self?.categoresdish = allDishes.categories ?? []
self?.popular = allDishes.populars ?? []
self?.specials = allDishes.specials ?? []
case .failure(let error): // when i load the load the data the control goes to here
print("faheem error is \(error.localizedDescription)")
ProgressHUD.showError()
}
}
}
extension HomeController : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
self.configureDisehsCell(tableView, cellForRowAt: indexPath)
}
func configureDisehsCell(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
guard let dishesCell = tableView.dequeueReusableCell(withIdentifier: String(describing: HomeTableViewCell.self), for: indexPath) as? HomeTableViewCell else {return UITableViewCell()}
dishesCell.categoreisData = self.categories[indexPath.row]
dishesCell.row = indexPath.row
dishesCell.categoriesDishsLoad = self.categoresdish
dishesCell.popularDishesLoad = self.popular
dishesCell.chiefSpecialsLoad = self.specials
return dishesCell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// return indexPath.row == 0 ? 140: 240
let row = indexPath.row
switch row {
case 0:
return 140
case 1:
return 260
case 2:
return 200
default:
return 0
}
}
}
enter code here
КЛАСС МАРШРУТА
enum Route{
static let baseUrl = "https://yummie.glitch.me"
case fetchAllCategories
var description: String{
switch self{
case .fetchAllCategories:
return "/dish-categories"
}
}
}
КЛАСС МЕТОДА
enum Method: String{
case get = "GET"
case post = "POST"
case delete = "DELETE"
case patch = "PATCH"
}
КЛАСС ПРИЛОЖЕНИЯ
enum AppError: LocalizedError{
case errorDecoding
case unknownError
case inValidUrl
case ServerError(String)
var errorDescription: String?{
switch self{
case .errorDecoding:
return "response could not be decoded"
case .unknownError:
return "i have no idea what the error is"
case .inValidUrl:
return "give me a valid url"
case .ServerError(let error):
return error
}
}
}
КЛАСС APIRESPONSE
struct ApiResponse: Decodable{
let status: Int //like 100,200,300
let message: String //message from the backend
let data: T? // we get the different types of data like int,string, custom types etc and convert json into particular strucures
let error: String? //errro from backend comes or not
}
ВСЕ КЛАССЫ МОДЕЛЕЙ
struct DishCategory: Decodable{
var id: String
var name: String
var image: String
}
struct Dish: Decodable{
var id:String
var name:String
var image:String
var description:String
var calories:Double
var formatedCalories:String{
return String(format: "%2f" , calories)
}
}
struct Orders{
var id: String
var name: String
var dish: Dish // kis dish pr order howa he
}
struct AllDishes: Decodable{
let categories: [DishCategory]?
let populars: [Dish]?
let specials: [Dish]?
}
Подробнее здесь: https://stackoverflow.com/questions/686 ... ackend-api
Получение ошибки при попытке декодировать данные в Swift через API бэкэнда. ⇐ IOS
Программируем под IOS
1730500320
Anonymous
Я пытаюсь получить данные через серверный API и получаю данные по функции запроса в сетевом классе, например
if let getData = data{
result = .success(getData)
let respondString = String(data:getData, encoding: .utf8) ?? "could not convert our data into string"
// print("backend response is \(respondString)") //here i'm getting data perfeclty
}
но я не знаю, почему данные не декодируются идеально, когда я вызываю сетевые вызовы в домашнем контроллере для загрузки данных, они не работают нормально. Я приложил все скриншоты как а также код сетевого класса, пожалуйста, помогите решить эту проблему.
NETWORKING CALSS:
struct NetworkService{
static let shared = NetworkService()
private init(){
}
func fetchAllCategories(completion: @escaping(Result)-> Void){
request(route: .fetchAllCategories, method: .get, completion: completion)
}
// 1.private function access in this struct not outsude the struct
private func createRequest(route: Route, method: Method, parameters : [String:Any]? = nil) -> URLRequest?
{
//baseUrl = "https://yummie.glitch.me/temp"
let urlString1 = Route.baseUrl + route.description //calling from route class
guard let url = URL(string: urlString1) else { return nil }//convet url into string
var urlRequest = URLRequest(url: url)
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
//rawvlaue return cases as a string
urlRequest.httpMethod = method.rawValue
if let params = parameters{
switch method{
case .get:
// https:// google.com/books?type=cartoon&page=1
var urlComponent = URLComponents(string: urlString1)
urlComponent?.queryItems = params.map {
URLQueryItem(name: $0, value: "\($1)")}
urlRequest.url = urlComponent?.url
case .post, .delete, .patch:
let bodyData = try? JSONSerialization.data(withJSONObject: params, options: [])
urlRequest.httpBody = bodyData
}
}
return urlRequest
}
//2. Create One Generic Function to Make Different Types of API Requests
private func request(route: Route,method: Method, parameters: [String: Any]? = nil, completion: @escaping(Result) -> Void){
guard let request = createRequest(route: route, method: method, parameters: parameters) else {//caling 1st function
completion(.failure(AppError.unknownError)) //calling error that define in APPErro class
return
}
URLSession.shared.dataTask(with: request){ (data, response, error) in
var result: Result?
if let getData = data{
result = .success(getData)
let respondString = String(data:getData, encoding: .utf8) ?? "could not convert our data into string"
// print("backend response is \(respondString)") //here i'm getting data perfeclty
}
else if let error = error{
result = .failure(error)
print("error is:\(error.localizedDescription)")
}
DispatchQueue.main.async {
print("success \(result)")
self.handleRequest(result: result , completion: completion)
}
}.resume()
}
//4.hnalde the api response from api response class and show to decoadlbe data that shows on api
private func handleRequest(result:Result?, completion: @escaping(Result) -> Void){
guard let result = result else {
completion(.failure(AppError.unknownError))
return
}
switch result {
case .success(let data):
let decoder = JSONDecoder()
guard let response = try? decoder.decode(ApiResponse.self, from: data) else {
completion(.failure(AppError.errorDecoding))
return
}
if let error = response.error{
completion(.failure(AppError.ServerError(error)))
}
if let decodedData = response.data{
completion(.success(decodedData))
}else{
completion(.failure(AppError.unknownError))
}
case .failure(let error):
completion(.failure(error))
}
}
}
КЛАСС ДОМАШНЕГО КОНТРОЛЛЕРА:
class HomeController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var categories: [String] = ["Food Category","Popular Dishes","Chief Specials"]
var categoresdish: [DishCategory] = []{
didSet{
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
var popular: [Dish] = []{
didSet{
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
var specials: [Dish] = []{
didSet{
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.loadData()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.register(UINib(nibName: String(describing: HomeTableViewCell.self), bundle: .main), forCellReuseIdentifier: String(describing: HomeTableViewCell.self))
}
private func loadData(){
ProgressHUD.show()
NetworkService.shared.fetchAllCategories { [weak self] (result) in
switch result{
case .success(let allDishes):
ProgressHUD.dismiss()
self?.categoresdish = allDishes.categories ?? []
self?.popular = allDishes.populars ?? []
self?.specials = allDishes.specials ?? []
case .failure(let error): // when i load the load the data the control goes to here
print("faheem error is \(error.localizedDescription)")
ProgressHUD.showError()
}
}
}
extension HomeController : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
self.configureDisehsCell(tableView, cellForRowAt: indexPath)
}
func configureDisehsCell(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
guard let dishesCell = tableView.dequeueReusableCell(withIdentifier: String(describing: HomeTableViewCell.self), for: indexPath) as? HomeTableViewCell else {return UITableViewCell()}
dishesCell.categoreisData = self.categories[indexPath.row]
dishesCell.row = indexPath.row
dishesCell.categoriesDishsLoad = self.categoresdish
dishesCell.popularDishesLoad = self.popular
dishesCell.chiefSpecialsLoad = self.specials
return dishesCell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// return indexPath.row == 0 ? 140: 240
let row = indexPath.row
switch row {
case 0:
return 140
case 1:
return 260
case 2:
return 200
default:
return 0
}
}
}
enter code here
КЛАСС МАРШРУТА
enum Route{
static let baseUrl = "https://yummie.glitch.me"
case fetchAllCategories
var description: String{
switch self{
case .fetchAllCategories:
return "/dish-categories"
}
}
}
КЛАСС МЕТОДА
enum Method: String{
case get = "GET"
case post = "POST"
case delete = "DELETE"
case patch = "PATCH"
}
КЛАСС ПРИЛОЖЕНИЯ
enum AppError: LocalizedError{
case errorDecoding
case unknownError
case inValidUrl
case ServerError(String)
var errorDescription: String?{
switch self{
case .errorDecoding:
return "response could not be decoded"
case .unknownError:
return "i have no idea what the error is"
case .inValidUrl:
return "give me a valid url"
case .ServerError(let error):
return error
}
}
}
КЛАСС APIRESPONSE
struct ApiResponse: Decodable{
let status: Int //like 100,200,300
let message: String //message from the backend
let data: T? // we get the different types of data like int,string, custom types etc and convert json into particular strucures
let error: String? //errro from backend comes or not
}
ВСЕ КЛАССЫ МОДЕЛЕЙ
struct DishCategory: Decodable{
var id: String
var name: String
var image: String
}
struct Dish: Decodable{
var id:String
var name:String
var image:String
var description:String
var calories:Double
var formatedCalories:String{
return String(format: "%2f" , calories)
}
}
struct Orders{
var id: String
var name: String
var dish: Dish // kis dish pr order howa he
}
struct AllDishes: Decodable{
let categories: [DishCategory]?
let populars: [Dish]?
let specials: [Dish]?
}
Подробнее здесь: [url]https://stackoverflow.com/questions/68652726/getting-an-error-when-trying-to-decode-the-data-in-swift-through-backend-api[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия