Как передать Encodable или Decodable в качестве параметра в Swift 4?

Я изучаю JSONParsing. Я следил за учебниками и получил следующее:

    guard let url = URL(string: "http://localhost/test-api/public/api/register") else { return }

    var request  = URLRequest(url: url)

    request.httpMethod = "POST"

    let newUser = User.init(name: self.collectionTF[0].text, email: self.collectionTF[1].text, password: self.collectionTF[2].text)

    do {

        let jsonBody = try JSONEncoder().encode(newUser)

        request.httpBody = jsonBody

    } catch { }

    URLSession.shared.dataTask(with: request) { (data, response, error) in

        guard let data = data else { return }

        do {

            let json = try JSONSerialization.jsonObject(with: data) as? [String:Any]

            print(json!)

            DispatchQueue.main.async {

            if json!["status"] as! Int == 200
            {
                GeneralHelper.shared.keepLoggedIn()

                NavigationHelper.shared.moveToHome(fromVC: self)
            }

            }

        } catch { print(error.localizedDescription)}

        }.resume()

Хорошо, вот что я сделал для регистрации. Теперь я хочу создать помощника, который будет делать то же самое с @escaping, поскольку мне всем нам нужен взамен проанализированный JSON.

Итак, я передаю endPoint как String, а затем пытаюсь передать этого нового пользователя, который является Encodable, он может быть и Decodable в будущем, но он выдает ошибку Cannot invoke 'encode' with an argument list of type '(Codable)'. Кто-нибудь может помочь? И лучше ли так, вызывая эту функцию несколько раз, когда дело касается JSONParsing?

Обновлено: - Итак, теперь я использую networkRequestfunction, и вот что я сделал.

 let newData = User.init(name: "Rob", email: "[email protected]", password: "12345678")

ApiHelper.sharedInstance.networkRequest_Post(urlString: "register", header: nil, encodingData: newData) { (response: User, urlRes, error) in
        <#code#> }

Теперь это дает мне эту ошибку: Cannot convert value of type '(User, _, _) -> ()' to expected argument type '(_?, HTTPURLResponse?, Error?) -> ()'. Любая помощь?

Я создал классы-оболочки. Попробуйте github.com/PrashantKT/AlamofireHelperLayer.

Prashant Tukadiya 26.10.2018 08:56
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
1
5 813
2

Ответы 2

Вы можете использовать Дженерики следующим образом ...

func requestWith<T>(method: HTTPMethod, action: String,  params: Parameters?, for type: T.Type, success: @escaping (AnyObject) -> Void, failure: @escaping (AnyObject) -> Void) where T: Codable {


//do your stuff..your logic goes here..see below example

     guard let serverData = response.data else {
           return
        }

   do {
     let decoder = JSONDecoder()
     let responseData = try decoder.decode(type, from: serverData)
       success(responseData as AnyObject)
    } catch {
      print("Error = \(error.localizedDescription)")
       failure(error.localizedDescription as AnyObject)
   }

}

Codable - это супер протокол Decodable & Encodable ... просто попробуйте.

Mahendra 26.10.2018 08:30

Неуказанный AnyObject не подходит для универсальной функции. Лучше func requestWith<T>(method: HTTPMethod, action: String, params: Parameters?, success: @escaping (T) -> Void, failure: @escaping (Error) -> Void) where T: Codable {

vadian 26.10.2018 08:31

Я знаю, здесь вы использовали JSONDecoder, поэтому я спрашиваю, что мне делать, если я хочу encode?

Rob13 26.10.2018 08:31

@vadian, это просто пример :)

Mahendra 26.10.2018 08:53

Да, но, пожалуйста, предложите лучшие примеры тем, кто копирует и вставляет код вместе.

vadian 26.10.2018 08:58

@vadian Можете ли вы показать мне пример или что-нибудь еще, где используются как JSONEncoder, так и Decoder? Или любой учебник, которому я могу следовать?

Rob13 26.10.2018 09:12

Отличный пример! Думаю, это меня просто зацепило дженериками ... ?

LinusGeffarth 08.04.2019 22:13

Я использовал ту же функциональность в своем проекте

Надеюсь, приведенный ниже код поможет

    func networkRequest_Post<T: Decodable, Q: Encodable>(urlString: String,header:[String:String]?,encodingData: Q,completion: @escaping (T?, HTTPURLResponse?, Error?) -> ()) {

    guard let url = URL(string: urlString) else { return }
    let config = URLSessionConfiguration.default
    config.timeoutIntervalForRequest = 300.0
    config.timeoutIntervalForResource = 300.0
    if header != nil{
        config.httpAdditionalHeaders = header
    }
    let session = URLSession(configuration: config)
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    do {
        let jsonBody = try JSONEncoder().encode(encodingData)
        request.httpBody = jsonBody
    } catch {}
    let task = session.dataTask(with: request) { (data,response, err) in

        if let response = response {
            print(response)
        }
        if let err = err {
            print("Failed to fetch data:", err.localizedDescription, "Error Description\(err)")
            return
        }
        guard let data = data else { return }
        do {
            print(String(data: data, encoding: String.Encoding.utf8) as Any)
            let dataReceived = try JSONDecoder().decode(T.self, from: data)
                completion(dataReceived,response as? HTTPURLResponse,err)
        } catch let jsonErr {
            print("Failed to serialize json:", jsonErr, jsonErr.localizedDescription)
            completion( nil,response as? HTTPURLResponse,jsonErr)
        }
    }
    task.resume()
}

Использовать -

         let newdata = User(name: "Abhi", email: "[email protected]", password: "123hguhj")
    networkRequest_Post(urlString: "YOUR_URL", header: nil, encodingData: newdata) { (RESPONSE_DATA:User?, URL_RESPONSE, ERROR) in
        // Do your network work here
    }

    struct User : Codable {
      var name: String?
      var email: String?
      var password: String?
    }

Хорошо, не могли бы вы показать мне такую ​​функцию, как вызов функции с декодируемым и кодируемым, извините, но мне все не так ясно, когда дело доходит до дженериков, я очень новичок в этом. Небольшой справочник мне поможет.

Rob13 26.10.2018 09:54

Нужен ли мне заголовок?

Rob13 26.10.2018 11:52

У меня было требование к заголовку, поэтому я добавил его. Я сделал это опцией и обновил свой код

Abhinav Jha 26.10.2018 11:57

Я обновил свой вопрос, пожалуйста, проверьте часть редактирования, это вызывает у меня головную боль. Вы знаете, что здесь не так?

Rob13 26.10.2018 17:08

Ожидаемый тип является необязательным, и вы передаете необязательное значение. Передайте значение, как показано ниже. ApiHelper.sharedInstance.networkRequest_Post (urlString: "register", header: nil, encodingData: newData) {(response: User ?, urlRes ?, error ?) в

Abhinav Jha 26.10.2018 17:21

Я обновил свой ответ и протестировал его в xcode, пожалуйста, проверьте мои ответы

Abhinav Jha 26.10.2018 17:30

Мой struct User был типа Encodable. я должен поменять его на Codable. Вот почему это не сработало.

Rob13 26.10.2018 17:39

Да, сделайте его кодируемым и дайте мне знать, сработало ли это

Abhinav Jha 26.10.2018 17:40

Позвольте нам продолжить обсуждение в чате.

Rob13 26.10.2018 17:42

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