aladinway / networkingexample Goto Github PK
View Code? Open in Web Editor NEWWrite a Networking Layer in Swift 4 using Alamofire 5 and Codable
Write a Networking Layer in Swift 4 using Alamofire 5 and Codable
Wonderful way to parse Json but way to generate URLRequest why ?? switch case case case case case imagine only 30 API I think will be a lot of cases ?? could you explain why you used switch case
Fatal error: RequestTaskMap consistency error: no events corresponding to task found.: file /Users/userName/iphone apps/CocoaPod/Xyloop/Pods/Alamofire/Source/RequestTaskMap.swift, line 115
@discardableResult
func performRequest<T: Decodable, F: URLRequestConvertible>(route : F,
decoder: JSONDecoder = JSONDecoder()) ->Future{
return Future(operation: { completion in
AppDelegate.sessionToken.request(route).responseDecodable(decoder: decoder, completionHandler: { (response: DataResponse) in
print("before switch reached") //this line of code isn't working, reponse isn't printing
switch response.result {
case .success(let value):
print("in success")
completion(.success(value))
case .failure(let error):
completion(.failure(error))
}
})
})
}
and this error came if I used AF.request, instead of requesting through session : Response could not be decoded because of error:
The data couldn’t be read because it isn’t in the correct format.
do you have any plan to update for swift 5 ?
How to send query parameters and field parameters in URL request?
i'm not able to add any parametre to GET request , any help ?
Showing error in APIClient.swift
Value of type 'DataRequest' has no member 'responseJSONDecodable', from below method
@discardableResult
private static func performRequest<T:Decodable>(route:APIRouter, decoder: JSONDecoder = JSONDecoder(), completion:@escaping (Result)->Void) -> DataRequest {
return Alamofire.request(route)
.responseJSONDecodable (decoder: decoder){ (response: DataResponse) in
completion(response.result)
}
}
How to get bearer base64 value from return response..
urlRequest.setValue("Bearer (base64 value)", forHTTPHeaderField: "Authorization")
hi i have
this routes
case login(username:String, password:String)
case register(username:String, email:String)
// Hevent
case createHevent(
id: String?,
ownerId: String,
name: String,
active: Bool,
duration: Int,
created: Int,
MemberPicture: [String]?
)
case readActiveHeventWithOwnerInfo
case readActiveHeventsByOwner(id: String)
case updateHevent()
case destroyHevent()
// Profile
case profile(id: String)
but getting error from
this case readActiveHeventsByOwner(id: String)
case profile(id: String)
readActiveHeventsByOwner Error Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x600000259bc0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x60400028ce90 [0x104c17c80]>{length = 16, capacity = 16, bytes = 0x10021ff50a0001030000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://10.0.1.3:8181/api/v1/findHangoutsByOwner/stBbRNbDh3BY3vyY0LBN3A, NSErrorFailingURLKey=http://10.0.1.3:8181/api/v1/findHangoutsByOwner/stBbRNbDh3BY3vyY0LBN3A, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.}
i have config about https in my info
here is my path
// MARK: - Path
private var path: String {
switch self {
case .login:
return "login"
case .register:
return "user/register"
case .createHevent:
return "hangout_channel"
case .readActiveHeventWithOwnerInfo:
return "hangoutWithOwnerDetails"
case .readActiveHeventsByOwner(let id):
return "findHangoutsByOwner/\(id)"
case .updateHevent:
return ""
case .destroyHevent:
return ""
// Profile
case .profile(let id):
return "account/findUserAccountDetails/\(id)"
}
}
struct Profile: Codable {
let firstname: String
let lastname: String
let ownerId: String
let gender: String
let dateOfBirth: String
let currentCountryAndCity, picture: String
enum CodingKeys: String, CodingKey {
case firstname = "firstname"
case lastname = "lastname"
case ownerId = "owner_id"
case gender = "gender"
case dateOfBirth = "date_of_birth"
case currentCountryAndCity = "current_country_and_city"
case picture = "picture"
}
}
static func createProfile(id: String?, ownerId: String, firstname: String, lastname: String, gender: String, dateOfBirth: String, picture: String, currentCountryAndCity: String) -> Future<Profile> {
return performRequest(route: APIRouter.profile(id: nil, ownerId: ownerId, firstname: firstname, lastname: lastname, gender: gender, dateOfBirth: dateOfBirth, picture: picture, currentCountryAndCity: currentCountryAndCity))
}
error profile response keyNotFound(CodingKeys(stringValue: "firstname", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"firstname\", intValue: nil) (\"firstname\").", underlyingError: nil))
but data is saving to my back end with this error
BEFORE Alamofire 5.0.0 beta.3 works 100%
@discardableResult
private static func performRequest<T:Decodable>(route:RequestConverterProtocol, decoder: JSONDecoder = JSONDecoder(), completion:@escaping (Result)->Void) -> DataRequest {
return AF.request(route)
.responseDecodable (decoder: decoder){
(response: DataResponse) in
completion(response.result)
}
}
AFTER Alamofire 5.0.0 beta.3 its ok?
@discardableResult
private static func performRequest<T:Decodable>(route:RequestConverterProtocol, decoder: JSONDecoder = JSONDecoder(), completion:@escaping (Result<T, AFError>)->Void) -> DataRequest {
return AF.request(route)
.responseDecodable (decoder: decoder){ (response: DataResponse<T, AFError>) in
completion(response.result)
}
}
Absolutely great articles, but I have a question.
It seems that the 'happy path' is handled within the project but I'm wondering how I go about handling an error that is returned from the server.
Let's say, for argument's sake, that there was an implementation that retrieves a specific article from the server, and that the user completes an action that causes a request to get an article from the API that doesn't exist. The server might respond with a 404 status code causing the failure case to get executed instead of success. The server returns an error response in the body, but Alamofire still tries to decode the response into the 'success' model, which it inevitably won't be able to do.
I would assume that creating an error response model would be in order here. Something which again conforms to decodable, but how would that be implemented within performRequest
function in our APIClient?
There would, of course, be the case where the error cannot be decoded into the error model, in which case we'd have to handle this separately.
Any ideas?
Thanks!
can we add some func for each request
now you have this
return performRequest(route: APIRouter.login(email: email, password: password))
}
static func userArticles(userID: Int) -> Future<[Article]> {
let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .formatted(.articleDateFormatter)
return performRequest(route: APIRouter.articles(userId: userID), decoder: jsonDecoder)
}
static func getArticle(articleID: Int) -> Future<Article> {
let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .formatted(.articleDateFormatter)
return performRequest(route: APIRouter.article(id: articleID), decoder: jsonDecoder)
}
so each model we have to create this typ of func but if you can create something like this with Generic
func get<T>{...}
func post<T>{...}
func put<T>{...}
func delete<T>{...}
func performRequest {...}
here some example code
https://gist.github.com/saroar/fc5fbd0c2ac4901904ab01ad3ac20048
Since this article is “part 2” and “part 1” already was using Alamofire, you should not cover how to integrate Alamofire in this article. Rather, you should put that in part one. Also, you say Carthage is the recommended way to install — according to whom? I think most likely Cocoapods is the more popular was, though it’s debatable, and also it can be installed via Swift Package Manager. Maybe it’s better to just refer to the install guide on the Alamofire github page…
I have this error in APIClient file
hi like to ask you how i can add
this is old NetworkLayer now i am trying to use ur code
let headers: HTTPHeaders = [
"Authorization": "Bearer \(sessionid)",
"X-CSRF-Token": "\(csrf)"
]
return headers
}``` in to your this project would like to help me little bit which part code will be best option to add this header part
return AF.request(route)
.responseDecodable (decoder: decoder){ (response: DataResponse) in
completion(response.result)
How to use different urls for different api's and different enviroments
Hey man, how are you?
I'm trying to make a simple post sending some headers, the servers hits an error 400 but the response shows as success, which is really odd.
This is the code I'm using in my APIClient:
private static func performRequest<T: Codable>(route: APIConfiguration, decoder: JSONDecoder = JSONDecoder(), completion:@escaping (Result<T>)->Void) -> DataRequest {
return AF.request(route).responseJSONDecodable(decoder: decoder) {
(response: DataResponse<T>) in completion(response.result)
}
}
static func postUser(completion:@escaping (Result<BaseResult>) -> Void) {
let jsonDecoder: JSONDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .formatted(.complexesDateFormatter)
performRequest(route: UserEndpoint.postUser(), decoder: jsonDecoder, completion: completion)
}
What I'm trying to do is not having to pass a "BaseResult":
struct BaseResult: Codable {
var code: Int?
}
This is UserEndpoint:
func asURLRequest() throws -> URLRequest {
let url: URL = try K.ProductionServer.baseURL.asURL()
var urlRequest: URLRequest = URLRequest(url: url.appendingPathComponent(path))
// HTTP Method
urlRequest.httpMethod = method.rawValue
let token: String = UserDefaults.standard.string(forKey: "Token") ?? ""
let bearerToken: String = "Bearer " + token
let bundleId: String = Bundle.footballNow.bundleIdentifier!
// Common Headers
urlRequest.setValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.acceptType.rawValue)
urlRequest.setValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.contentType.rawValue)
urlRequest.setValue(bearerToken, forHTTPHeaderField: HTTPHeaderField.authentication.rawValue)
urlRequest.setValue(bundleId, forHTTPHeaderField: HTTPHeaderField.bundleIdentifier.rawValue)
return urlRequest
}
Any thoughts?
Thanks
work with some apis and the majority gives ( Response could not be decoded because of error: The data couldn’t be read because it isn’t in the correct format. ) and I am sure the model is okay and I implemented it manually and with JSON model websites (jsoncafe as a example)
fixed
For success case decoders work as aspected.
But in error cases we have different json response.
How can we handle error cases?
i have issue when i try Run your project (Use of unresolved identifier 'AF')
what AF stand for ?
return AF.request(route)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.