126 lines
5.5 KiB
Swift
126 lines
5.5 KiB
Swift
import Foundation
|
|
import RxSwift
|
|
|
|
class Api {
|
|
private static func genError(_ msg: String, suggestion: String, code: Int = 0) -> Error {
|
|
return NSError(domain: "", code: code, userInfo: [NSLocalizedDescriptionKey: msg, NSLocalizedRecoverySuggestionErrorKey: suggestion])
|
|
}
|
|
|
|
private static func createRequest<T>(api: String, method: String, body: [String: T]? = nil) -> URLRequest? where T: LosslessStringConvertible {
|
|
guard var urlComponents = URLComponents(string: Constants.baseUrl + api) else { return nil }
|
|
|
|
if let body = body, method.uppercased() == "GET" {
|
|
urlComponents.queryItems = body.map { URLQueryItem(name: $0, value: String($1)) }
|
|
}
|
|
|
|
var request = URLRequest(url: urlComponents.url!)
|
|
request.httpMethod = method
|
|
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
request.addValue("application/json", forHTTPHeaderField: "Accept")
|
|
request.addValue("Bearer " + Settings.shared.user.token, forHTTPHeaderField: "Authorization")
|
|
|
|
if let body = body, method.uppercased() != "GET" {
|
|
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
|
|
}
|
|
|
|
return request
|
|
}
|
|
|
|
private static func makeRequest<T, U>(api: String, method: String, body: [String: U]? = nil) -> Observable<T> where T: Decodable, U: LosslessStringConvertible {
|
|
guard let request = self.createRequest(api: api, method: method, body: body) else {
|
|
return Observable.error(self.genError("Error creating request", suggestion: ""))
|
|
}
|
|
|
|
return URLSession.shared.rx.data(request: request).map { data in
|
|
// let str = String(data: data, encoding: .utf8)
|
|
// print("================================")
|
|
// print(str?.replacingOccurrences(of: "\\\"", with: "\""))
|
|
// print("================================")
|
|
let resp = try JSONDecoder().decode(Response<T>.self, from: data)
|
|
if resp.success {
|
|
return resp.data!
|
|
} else {
|
|
throw self.genError(resp.error!, suggestion: "")
|
|
}
|
|
}
|
|
}
|
|
|
|
public static func refreshFbToken() -> Observable<Void> {
|
|
guard let token = Settings.shared.user.googleIdToken, let refreshToken = Settings.shared.user.googleRefreshToken, let jwt = JWT(string: token), jwt.expired else {
|
|
return .just(())
|
|
}
|
|
|
|
let refreshUrlString = Constants.fbRefreshToken + "?key=" + Constants.fbApiKey
|
|
|
|
let body = [
|
|
"grantType": "refresh_token",
|
|
"refreshToken": refreshToken
|
|
]
|
|
|
|
if let url = URL(string: refreshUrlString) {
|
|
var request = URLRequest(url: url)
|
|
request.httpMethod = "POST"
|
|
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
|
|
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
request.addValue(Constants.fbClientVersion, forHTTPHeaderField: "X-Client-Version")
|
|
request.addValue(Constants.vin01BUndleId, forHTTPHeaderField: "X-Ios-Bundle-Identifier")
|
|
request.addValue(Constants.fbUserAgent, forHTTPHeaderField: "User-Agent")
|
|
return URLSession.shared.rx.json(request: request).map { resp in
|
|
guard let json = resp as? [String: Any] else { return }
|
|
if let newToken = json["id_token"] as? String {
|
|
Settings.shared.user.googleIdToken = newToken
|
|
print("Token was successfully refresh to: \(newToken)")
|
|
}
|
|
if let newRefreshToken = json["refresh_token"] as? String {
|
|
Settings.shared.user.googleRefreshToken = newRefreshToken
|
|
}
|
|
}.catchError { error in
|
|
print(error)
|
|
return .just(())
|
|
}
|
|
} else {
|
|
return .just(())
|
|
}
|
|
}
|
|
|
|
public static func login(username: String, password: String) -> Observable<User> {
|
|
let body = [
|
|
"login": username,
|
|
"password": password
|
|
]
|
|
return self.makeRequest(api: "user/login", method: "POST", body: body)
|
|
}
|
|
|
|
public static func signup(username: String, password: String) -> Observable<User> {
|
|
let body = [
|
|
"login": username,
|
|
"password": password
|
|
]
|
|
return self.makeRequest(api: "user/signup", method: "POST", body: body)
|
|
}
|
|
|
|
public static func getVehicles(with filter: Filter) -> Observable<[Vehicle]> {
|
|
let body = [
|
|
"limit": "0", // Unlimited
|
|
"query": filter.searchString
|
|
]
|
|
return self.makeRequest(api: "vehicles", method: "GET", body: body)
|
|
}
|
|
|
|
public static func checkVehicle(by number: String, force: Bool = false) -> Observable<Vehicle> {
|
|
return self.refreshFbToken().flatMap { () -> Observable<Vehicle> in
|
|
var body = [
|
|
"number": number,
|
|
"forceUpdate": String(force)
|
|
]
|
|
if let token = Settings.shared.user.googleIdToken {
|
|
body["googleIdToken"] = token
|
|
}
|
|
return self.makeRequest(api: "vehicles/check", method: "POST", body: body).map { (vehicle: Vehicle) -> Vehicle in
|
|
vehicle.addedDate = Date().timeIntervalSince1970*1000
|
|
return vehicle
|
|
}
|
|
}
|
|
}
|
|
}
|