Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .DS_Store
Binary file not shown.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ DerivedData/
*.perspectivev3
!default.perspectivev3
xcuserdata/
*.DS_Store
##xcshareddata

## Other
*.moved-aside
Expand Down Expand Up @@ -46,7 +48,9 @@ playground.xcworkspace
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
iOSBooks/Pods/
iOSBooks/iOSBooks.xcworkspace
iOSBooks/Podfile.lock

# Carthage
#
Expand Down
Binary file removed iOSBooks/.DS_Store
Binary file not shown.
19 changes: 19 additions & 0 deletions iOSBooks/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Uncomment the next line to define a global platform for your project
platform :ios, '12.0'

target 'iOSBooks' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!

# Pods for iOSBooks
pod 'PromiseKit'
pod 'IQKeyboardManagerSwift'

target 'iOSBooksTests' do
inherit! :search_paths
# Pods for testing
pod 'Quick', '~> 2.1.0'
pod 'Nimble', '~> 8.0.1'
end

end
205 changes: 204 additions & 1 deletion iOSBooks/iOSBooks.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions iOSBooks/iOSBooks/Data/Clients/BooksClient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// BooksClient.swift
// iOSBooks
//
// Created by Guilherme Antunes Ferreira on 28/08/19.
// Copyright © 2019 Guilherme Antunes. All rights reserved.
//

import Foundation
import PromiseKit

class BooksClient {

let apiClient: APIClient

init(apiClient: APIClient = APIClient()) {
self.apiClient = apiClient
}

func fetchBooksList() -> Promise<BooksList> {
return apiClient.request(model: BooksList.self, BooksAPI.list.request)
}
}
67 changes: 67 additions & 0 deletions iOSBooks/iOSBooks/Data/Endpoints/BooksAPI.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//
// BooksAPI.swift
// iOSBooks
//
// Created by Guilherme Antunes Ferreira on 28/08/19.
// Copyright © 2019 Guilherme Antunes. All rights reserved.
//

import Foundation

enum BooksAPI: Endpoint {

case list

var path: String {
switch self {
case .list:
return "https://www.googleapis.com/books/v1/volumes"
}
}

var headers: [String : String]? {
switch self {
case .list:
return nil
}
}

var body: Data? {
switch self {
case .list:
return nil
}
}

var httpMethod: String {
switch self {
case .list:
return "GET"
}
}

var queryItems: [URLQueryItem]? {
switch self {
case .list:
let subjectItem = URLQueryItem(name: "q", value: "ios")
let maxResultsItem = URLQueryItem(name: "maxResults", value: "20")
let startIndexItem = URLQueryItem(name: "startIndex", value: "0")
return [subjectItem, startIndexItem, maxResultsItem]
}
}

var request: URLRequest {
switch self {
case .list:
guard var components = URLComponents(string: path) else { fatalError() }
components.queryItems = queryItems
guard let url = components.url else { fatalError() }
var request = URLRequest(url: url)
request.allHTTPHeaderFields = headers
request.httpMethod = httpMethod
request.httpBody = body
return request
}
}
}

24 changes: 24 additions & 0 deletions iOSBooks/iOSBooks/Data/Models/Book.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// Book.swift
// iOSBooks
//
// Created by Guilherme Antunes Ferreira on 28/08/19.
// Copyright © 2019 Guilherme Antunes. All rights reserved.
//

import Foundation

class Book: Codable {
let authors: [String]?
let title: String?
let subtitle: String?
let description: String?
let imageLinks: ImageLinks?

enum CodingKeys: String, CodingKey {
case authors, title, subtitle, description, imageLinks
}
}



18 changes: 18 additions & 0 deletions iOSBooks/iOSBooks/Data/Models/BooksList.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// BooksList.swift
// iOSBooks
//
// Created by Guilherme Antunes Ferreira on 28/08/19.
// Copyright © 2019 Guilherme Antunes. All rights reserved.
//

import Foundation

class BooksList: Codable {
let items: [Item]?
let totalItems : Int?

enum CodingKeys: String, CodingKey {
case items, totalItems
}
}
19 changes: 19 additions & 0 deletions iOSBooks/iOSBooks/Data/Models/ImageLinks.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// ImageLinks.swift
// iOSBooks
//
// Created by Guilherme Antunes Ferreira on 28/08/19.
// Copyright © 2019 Guilherme Antunes. All rights reserved.
//

import Foundation

class ImageLinks: Codable {
let smallThumbnail: String?
let thumbnail: String?

enum CodingKeys: String, CodingKey {
case smallThumbnail, thumbnail
}

}
21 changes: 21 additions & 0 deletions iOSBooks/iOSBooks/Data/Models/Item.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Item.swift
// iOSBooks
//
// Created by Guilherme Antunes Ferreira on 28/08/19.
// Copyright © 2019 Guilherme Antunes. All rights reserved.
//

import Foundation

class Item: Codable {
let id: String?
let book: Book?
let salesInfo : SalesInfo?

enum CodingKeys: String, CodingKey {
case book = "volumeInfo"
case id
case salesInfo = "saleInfo"
}
}
14 changes: 14 additions & 0 deletions iOSBooks/iOSBooks/Data/Models/SalesInfo.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// SalesInfo.swift
// iOSBooks
//
// Created by Guilherme Antunes Ferreira on 28/08/19.
// Copyright © 2019 Guilherme Antunes. All rights reserved.
//

import Foundation

class SalesInfo: Codable {
let country: String?
let buyLink: String?
}
61 changes: 61 additions & 0 deletions iOSBooks/iOSBooks/Data/Network/APIClient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// APIClient.swift
// iOSBooks
//
// Created by Guilherme Antunes Ferreira on 28/08/19.
// Copyright © 2019 Guilherme Antunes. All rights reserved.
//

import Foundation
import PromiseKit

enum CustomError: Error {
case connectionError(String)
case mappingError(String)
case APIError(String)
case generalError(String)
case deallocatedClass(String)
}

class APIClient {

let connectionChecker: Reachability
let decoder: JSONDecoder
let session: URLSession

init(connectionChecker: Reachability = Reachability(), decoder: JSONDecoder = JSONDecoder(), session: URLSession = URLSession.shared) {
self.connectionChecker = connectionChecker
self.decoder = decoder
self.session = session
}

func request<T: Codable>(model: T.Type, _ request: URLRequest) -> Promise<T> {
return Promise<T> { [weak self] seal in
guard let _self = self else {
print("Class deinitialized!")
return
}

guard connectionChecker.isConnected else {
seal.reject(CustomError.connectionError("Por favor, verifique sua conexão com a internet!"))
return
}

session.dataTask(with: request, completionHandler: { (data, response, error) in
guard let data = data else {
seal.reject(CustomError.APIError(error?.localizedDescription ?? "Ocorreu um erro inesperado, por favor, tente novamente!"))
return
}

guard let model = try? _self.decoder.decode(T.self, from: data) else {
seal.reject(CustomError.mappingError("Houve um erro ao fazer o parse do modelo \(T.self)!"))
return
}

seal.fulfill(model)
}).resume()
}
}

}

18 changes: 18 additions & 0 deletions iOSBooks/iOSBooks/Data/Network/Endpoint.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Endpoint.swift
// iOSBooks
//
// Created by Guilherme Antunes Ferreira on 28/08/19.
// Copyright © 2019 Guilherme Antunes. All rights reserved.
//

import Foundation

protocol Endpoint {
var path: String { get }
var headers: [String: String]? { get }
var body: Data? { get }
var httpMethod: String { get }
var request: URLRequest { get }
var queryItems: [URLQueryItem]? { get }
}
36 changes: 36 additions & 0 deletions iOSBooks/iOSBooks/Data/Network/Reachability.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// Reachability.swift
// iOSBooks
//
// Created by Guilherme Antunes Ferreira on 28/08/19.
// Copyright © 2019 Guilherme Antunes. All rights reserved.
//

import Foundation
import SystemConfiguration

class Reachability {
var isConnected: Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
zeroAddress.sin_family = sa_family_t(AF_INET)

guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, $0)
}
}) else {
return false
}

var flags: SCNetworkReachabilityFlags = []
if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
return false
}

let isReachable = flags.contains(.reachable)
let needsConnection = flags.contains(.connectionRequired)

return (isReachable && !needsConnection)
}
}
7 changes: 1 addition & 6 deletions iOSBooks/iOSBooks/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,9 @@
//

import UIKit
import PromiseKit

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}


}