I am trying to save the user in UserDefaults from a struct that fetches the data from an API when a user logs in successfully.
Here is my Webservice class:
import Foundation
import UIKit
struct Resource<T: Codable> {
    let url : URL
    let httpMethod = HTTPMethod.post
    var body : Data? = nil
}
extension Resource {
    init(url: URL) {
        self.url = url
    }
}
enum HTTPMethod : String {
    case get = "GET"
    case post = "POST"
}
 enum NetworkingError: Error {
        case domainError
        case badResponse
        case encodingError
        case decodingError
    }
class Webservice {
    func load<T>(resource: Resource<T>, caller: UIViewController ,completion: @escaping (Result<T, NetworkingError>) -> Void) {
            var request = URLRequest(url: resource.url)
            request.httpMethod = resource.httpMethod.rawValue
            request.httpBody = resource.body
            request.addValue("application/JSON", forHTTPHeaderField: "Content-Type")
            URLSession.shared.dataTask(with: request) { (data, response, error) in
                guard let data = data, error == nil else {
                    return completion(.failure(.domainError))
                }
                let json = try? JSONSerialization.jsonObject(with: data, options: [])
                print(json)
                do {
                let result = try JSONDecoder().decode(T.self, from: data)
//save to UserDefaults
                    UserDefaults.standard.set(PropertyListEncoder().encode(T), forKey: "user")\\ here I am getting error that T.type does not conform to Encodable protocol.
completion(.success(result))
                }catch {
                    do {
                        if let result = try? JSONDecoder().decode(LoginErrorResponse.self, from: data){
                    print(result.errors.msg)
                        DispatchQueue.main.async {
                            let alert = AlertService().alert(message: "\(result.errors.msg[0])")
                            caller.present(alert, animated: true)
                        }
                        completion(.failure(.decodingError))
                    }
                        if let result = try? JSONDecoder().decode(SignUpErrorResponse.self, from: data){
                        print(result.errors.msg)
                            DispatchQueue.main.async {
                                let alert = AlertService().alert(message: "\(result.errors.msg)")
                                caller.present(alert, animated: true)
                            }
                            completion(.failure(.decodingError))
                        }
                }
            }
            }.resume()
        }
    }
Here is my model class:
import Foundation
struct User: Encodable, Decodable {
    let name: String
    let email: String
    let password: String
    let first_name: String
    let last_name: String
}
extension User {
    static var all : Resource<User> = {
        guard let url = URL(string: "http://orderahead.gagzweblab.xyz:3001/login") else {
                    fatalError("url is incorrect")
               }
        return Resource<User>(url: url)
    }()
    static func create(vm : UserViewModel) -> Resource<UserResponseModel?> {
        let user = User(vm)
        guard let url = URL(string: "http://orderahead.gagzweblab.xyz:3001/register") else {
             fatalError("url is incorrect")
        }
        guard let data = try? JSONEncoder().encode(user) else {
             fatalError("error encoding user")
        }
        var resource = Resource<UserResponseModel?>(url: url)
        resource.body = data
        return resource
    }
}
extension User {
    init?(_ vm: UserViewModel) {
         let email = vm.email
         let password = vm.password
        let first_name = vm.first_name
        let last_name = vm.last_name
        let name = vm.name
        self.password = password
        self.email = email
        self.first_name = first_name
        self.last_name = last_name
        self.name = name
    }
}
And here is my view model:
import Foundation
struct UserViewModel : Codable {
    let user : User
}
extension UserViewModel {
    var name : String {
        return self.user.name
    }
    var email : String {
        return self.user.email
    }
    var password : String {
        self.user.password
    }
    var first_name: String {
        self.user.first_name
    }
    var last_name: String {
        self.user.last_name
    }
}
This is how I am calling it:
let login = LoginUser(email: email, password: password)
                   let vm = UserViewModel(loginUser: login)
Webservice().load(resource: User.create(vm: vm), caller: self) { (result) in
My model and view model conform to Codable as well as my Resource is Codable too.
What is the reason of the error that T.type does not conform to protocol Encodable? How to resolve it?
Is this approach to send and receive data appropriate?
 
     
    