Недавно писал метод для универсального сетевого запроса. При использовании метода, использовался словарик с ключами, которые каждый раз передавались в запросе для идентификации приложения
Каждый раз при вызове метода нужно было формировать тело запроса с кастомными полями и этими ключами, что выглядело как то громоздко. В общем, проблема решается подготовкой словаря с последующем добавлением к нему словаря ключей уже внутри метода запроса к серверу.
Может кому пригодится расширение стандартного словаря:
extension Dictionary {
mutating func merge(with dictionary: Dictionary) {
dictionary.forEach { updateValue($1, forKey: $0) }
}
func merged(with dictionary: Dictionary) -> Dictionary {
var dict = self
dict.merge(with: dictionary)
return dict
}
}
Ну и пример:
let keys = ["appId": "<...>", "clientId": "<...>", "secretKey": "<...>"]
let bodyRequest = ["description": "Bla Bla Bla", "title": "Bla Bla Bla"]
let body: [String : Any] = bodyRequest.merged(with: keys)
На выходе будет:
["description": "Bla Bla Bla", "title": "Bla Bla Bla", "appId": "<...>", "clientId": "<...>", "secretKey": "<...>"]
Ну и пример как формировать такой запрос в Alamofire:
fileprivate func requestToServerPOST(method: RTConfig.RTScorocodeAPI, bodyRequest: [String: Any], callback: @escaping (_ obj: Any?) -> Void) {
let headers = ["Content-Type": "application/json"]
let body: [String : Any] = bodyRequest.merged(with: keys)
let adress = "\(RTConfig.RTScorocodeAPI.baseLink.rawValue)\(method.rawValue)"
Alamofire.request(adress, method: .post, parameters: body, encoding: JSONEncoding.default, headers: headers)
.authenticate(user: "", password: "***** Hidden credentials *****")
.validate(statusCode: 200..<300)
.responseJSON { response in
if (response.result.error == nil) {
callback(response.result.value)
} else {
debugPrint("HTTP Request failed: \(response.result.error)")
callback(nil)
}
}
}
А так как недавно мелькал вопрос по работе с данными в Alamofire, их можно мапить:
func insertStationToServer(callback: @escaping (_ _id: String) -> Void) {
let body: [String : Any] = [
"coll": "stations",
"doc": ["station": "INSERT new", "url": "http://swiftbook.ru"]
]
requestToServerPOST(method: .insert, bodyRequest: body) { response -> Void in
if response != nil {
if JSONSerialization.isValidJSONObject(response!) {
if let station = Mapper<RTScorocodeStation>().map(JSONObject: response) {
print("[STATION ID] = \(station._id!)")
}
}
}
}
}
Про маппинг здесь уже обсуждалось, свои модельки сами реализуете!