swiftswift-package

how I can make xcode access my table in my API through a swiftPackage?


I have a database (PostgreSQL) with data, I've create an API (apinetopark) (with vapor) and an app netopark(macOS,swiftUI).

My API successfully (localhost) reach the database and return my data. So I tried to create an Swiftpackage (apinetoparkclient) to return a view of my data (build successful) but when I import my module I can't reach my data[table] ...

My app Homeviewmodel :

import Foundation
import apinetoparkclient

class HomeViewModel: ObservableObject {
    @Published var societies: [APINetoparkclient.CLT_CLT_CLIENT] = []
    @Published var selectedTab: HomeTab = .parc

    enum HomeTab {
        case parc
        case societies
        case equipment
        case users
        case reports
        case settings
    }

    func fetchSocieties() {
        APINetoparkclient.shared.fetchSocieties { result in
            switch result {
            case .success(let societies):
                DispatchQueue.main.async {
                    self.societies = societies
                }
            case .failure(let error):
                print("Error fetching societies:", error.localizedDescription)
            }
        }
    }
}

The error:

/Users/egage/Documents/netopark/NetoPark/NetoPark/HomeViewModel/HomeViewModel.swift:5:50 'CLT_CLT_CLIENT' is not a member type of class 'apinetoparkclient.apinetoparkclient'

'apinetoparkclient' declared here (/Users/egage/Library/Developer/Xcode/DerivedData/NetoPark-gtrezayhmddlsdgrfbavwkdwplxf/SourcePackages/checkouts/apinetoparkclient/Sources/apinetoparkclient/apinetoparkclient.swift)

The apinetoparkclient:

import Foundation

public class APINetoparkclient {
    public static let shared = APINetoparkclient()
    private let baseURL = "http://127.0.0.1:8080/"
    private init() { }
    public var urlSession: URLSession = URLSession.shared

    public func fetchSocieties(completion: @escaping (Result<[CLT_CLT_CLIENT], Error>) -> Void) {
        guard let url = URL(string: "\(baseURL)/societies") else {
            completion(.failure(apinetoparkclientError.invalidURL))
            return
        }
        URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            if let data = data {
                do {
                    let decoder = JSONDecoder()
                    decoder.keyDecodingStrategy = .convertFromSnakeCase
                    let societies = try decoder.decode([CLT_CLT_CLIENT].self, from: data)
                    completion(.success(societies))
                } catch {
                    completion(.failure(error))
                }
            } else {
                completion(.failure(apinetoparkclientError.badResponse))
            }
        }.resume()
    }
}

public struct CLT_CLT_CLIENT: Identifiable, Codable {
    public let id: UUID?
    var raisonsociale: String
    
    public init(id: UUID?, raisonsociale: String) {
        self.id = id
        self.raisonsociale = raisonsociale
    }
}

public enum apinetoparkclientError: Error {
    case invalidURL
    case badResponse
}

I've tried to make public all the variables even my table :/ I expect that my netopark app import and load my module who return the data (List in a view) in my database reached by my API.

done=> my API is running and returning my data, my package build successfully, I clean, rebuild and reload at every changes.


Solution

  • It seems CLT_CLT_CLIENT is not declared inside the APINetoparkclient namespace so it's not needed to use it as a prefix:

    @Published var societies: [CLT_CLT_CLIENT] = []
    

    But the error might exist because your package's target is named APINetoparkclient which is also the name of a class inside your target. In such a case the compiler might be confused: is APINetoparkclient referring to the target namespace (e.g. like SwiftUI) or is related to the class APINetoparkclient inside this target?

    I would advice to never name a type the same as the target/package that owns it. It very often lead to naming issues for a client.