Skip to content

Instantly share code, notes, and snippets.

@badrinathvm
Last active May 16, 2020 21:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save badrinathvm/e5372d135bad1d909c4422b0777aa797 to your computer and use it in GitHub Desktop.
Save badrinathvm/e5372d135bad1d909c4422b0777aa797 to your computer and use it in GitHub Desktop.
Combine Networking
import Combine
struct Welcome: Codable {
let page: Int
let results: [Result]
let totalPages, totalResults: Int
init(page:Int = 0, results: [Result], totalPages:Int = 0, totalResults: Int = 0) {
self.page = page
self.results = results
self.totalPages = totalPages
self.totalResults = totalResults
}
enum CodingKeys: String, CodingKey {
case page, results
case totalPages = "total_pages"
case totalResults = "total_results"
}
}
// MARK: - Result
struct Result: Codable,Identifiable, Hashable {
let id: Int
let video: Bool
let voteCount: Int
let voteAverage: Double
let title, releaseDate: String
let originalLanguage: OriginalLanguage
let originalTitle: String
let genreIDS: [Int]
let backdropPath: String
let adult: Bool
let overview, posterPath: String
let popularity: Double
enum CodingKeys: String, CodingKey {
case id, video
case voteCount = "vote_count"
case voteAverage = "vote_average"
case title
case releaseDate = "release_date"
case originalLanguage = "original_language"
case originalTitle = "original_title"
case genreIDS = "genre_ids"
case backdropPath = "backdrop_path"
case adult, overview
case posterPath = "poster_path"
case popularity
}
}
enum OriginalLanguage: String, Codable {
case en = "en"
}
class Network {
var cancellable: AnyCancellable?
func fetchData(completion: @escaping (Welcome) -> Void) {
let url = URL(string: "https://gist.githubusercontent.com/badrinathvm/b1ca7949af2f4b9198ea057c167f6d35/raw/8ff20ccc49b3f76d9ebedc8cb33c75d667faf85f/movie.json")!
// here Welcome is the name of the model we are decoding.
let publisher:AnyPublisher<Welcome, HTTPError> = decode(url: url)
self.cancellable = publisher.sink(receiveCompletion: { (completion) in
switch completion {
case .finished: print(completion)
case .failure(let error):
print(error.localizedDescription)
}
}) { (results) in
completion(results)
}
}
// using generics.
func decode<T:Decodable>(url : URL) -> AnyPublisher<T, HTTPError> {
return URLSession.shared.dataTaskPublisher(for: url)
.tryMap { output in
guard let response = output.response as? HTTPURLResponse, response.statusCode == 200 else { throw HTTPError.statusCode }
return output.data
}
.decode(type: T.self, decoder: JSONDecoder())
.mapError { error in
return HTTPError.statusCode
}
.eraseToAnyPublisher()
}
// post request
func decodePost() {
let string = "http://www.thisismylink.com/postName.php"
//query params
let queryItems = [
URLQueryItem(name: "id", value: "13"),
URLQueryItem(name: "name", value: "Jack & Jill")]
//setting query params
var urlComponents = URLComponents(string: string)
urlComponents?.queryItems = queryItems
//get he url
guard let url = urlComponents?.url else { return }
//create a url request
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
URLSession.shared.dataTaskPublisher(for: request)
.tryMap { output in
guard let response = output.response as? HTTPURLResponse , (200...299).contains(response.statusCode) else { throw HTTPError.statusCode }
return output.data
}
.eraseToAnyPublisher()
.sink(receiveCompletion: { (completion) in
switch completion {
case .finished : print("finished")
case .failure(let error): print(error.localizedDescription)
}
}) { (data) in
print(data)
}.store(in: &cancellables)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment