Swift Generic URLRequest - PullRequest
       7

Swift Generic URLRequest

0 голосов
/ 07 мая 2019

Я пытаюсь создать функцию createRequest, которую я могу повторно использовать для всех моих сетевых вызовов, некоторые требуют публикации JSON, а другие нет, поэтому я думал о создании функции, которая принимает необязательный универсальный объект; что-то в теории, как это:

struct Person: Codable {

var fName: String
var lName: String

}

struct Location: Codable {

 var city: String
 var state: String

}

let data = Person(fName: "John", lName: "Smith")
let location = Location(city: "Atlanta", state: "Georgia")

createRequest(withData: data)
createRequest(withData: location)

 private func createRequest(withData:T) throws -> URLRequest { 

        var newRequest = URLRequest(url: URL(string: "\(withUrl)")!)

        newRequest.httpMethod = method.rawValue

       if let data = withData {

            newRequest.setBody = data

         }

        if withAPIKey {

            newRequest.setValue(apiKey, forHTTPHeaderField: "APIKEY")

        }

        return newRequest

    }

Я хотел бы вернуть URLRequest с возможностью передачи различных объектов JSON этой функции. Я читал, что вы не можете сделать это таким образом, если вы не определили тип в функции возврата, но я не могу определить свой объект в возвращении.

1 Ответ

1 голос
/ 07 мая 2019

Предисловие: Этот код представляет собой беспорядок противоречивых отступов и ненужных пробелов (он читается как эссе с двойным интервалом, смеется), я его убрал.

Похоже, ваша функция должна занять T,но не просто T, а тот, который ограничен до Encodable.Это обычное наблюдение: более общие универсальные параметры совместимы с большим количеством типов, но мы можем сделать с ними меньше.Содержа от T до Encodable, мы можем использовать его с JSONEncoder.encode.

Метка withData: является неправильным, потому что этот параметр не будет иметь тип Data.Что-то вроде withBody: будет работать лучше.

import Foundation

struct Person: Codable {
    var fName: String
    var lName: String
}

struct Location: Codable {
    var city: String
    var state: String
}

// stubs for making compilation succeed
let apiKey = "dummy"
let withAPIKey = true
enum HTTPMethod: String { case GET } 

private func createRequest<Body: Encodable>(method: HTTPMethod, url: URL, withBody body: Body) throws -> URLRequest { 

    var newRequest = URLRequest(url: url)
    newRequest.httpMethod = method.rawValue

    newRequest.httpBody = try JSONEncoder().encode(body)

    if withAPIKey {
        newRequest.setValue(apiKey, forHTTPHeaderField: "APIKEY")
    }

    return newRequest
}

let data = Person(fName: "John", lName: "Smith")
let location = Location(city: "Atlanta", state: "Georgia")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...