Newer
Older
bremer-ios-app / BremerApp / ViewModel / BremerApi.swift
yhornisse on 10 Sep 2023 4 KB Initial Commit
//
//  RemoteAudioService.swift
//  Bremer
//
//  Created by yhornisse on 2023/07/17.
//

import Combine
import Foundation

public func getApiFailureTextByError(_ error: Error) -> String {
    switch (error) {
    case is BremerLoginError:
        return "ログインしてください"
    case is BremerConnectionError:
        return "Connection error"
    default:
        return error.localizedDescription
    }
}

public func sendApi<T: Codable>(url: URL) -> AnyPublisher<T, Error> {
    let cookie = UserDefaults.standard.string(forKey: "JSESSIONID")
    if cookie == nil {
        return Future<T, Error> { promise in
            promise(.failure(BremerConnectionError()))
        }.eraseToAnyPublisher()
    }
    var request:URLRequest = URLRequest(url: url)
    request.setValue("JSESSIONID=\(cookie!)", forHTTPHeaderField: "Cookie")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    let jsonDecoder = JSONDecoder()
    jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase
    return URLSession.shared.dataTaskPublisher(for: request)
        .tryMap { res in
            guard let httpResponse = res.response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
                throw BremerConnectionError()
            }
            guard let mimeType = httpResponse.mimeType else {
                throw BremerConnectionError()
            }
            if mimeType == "text/html" {
                guard let url = httpResponse.url else {
                    throw BremerConnectionError()
                }
                if url.path == "/bremer/login.html" {
                    throw BremerLoginError()
                }
            }
            return res.data
        }
        .decode(type: T.self, decoder: jsonDecoder)
        .receive(on: DispatchQueue.main)
        .eraseToAnyPublisher()
}


public func sendApi(url: URL, httpMethod: String) -> AnyPublisher<Any, Error> {
    let cookie = UserDefaults.standard.string(forKey: "JSESSIONID")
    if cookie == nil {
        return Future<Any, Error> { promise in
            promise(.failure(BremerConnectionError()))
        }.eraseToAnyPublisher()
    }
    var request:URLRequest = URLRequest(url: url)
    request.httpMethod = httpMethod
    request.setValue("JSESSIONID=\(cookie!)", forHTTPHeaderField: "Cookie")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    let jsonDecoder = JSONDecoder()
    jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase
    return URLSession.shared.dataTaskPublisher(for: request)
        .tryMap { res in
            guard let httpResponse = res.response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
                throw BremerConnectionError()
            }
            return res
        }
        .receive(on: DispatchQueue.main)
        .eraseToAnyPublisher()
}

public func sendApi<U: Codable>(url: URL, httpMethod: String, requestBody: U) -> AnyPublisher<Any, Error> {
    let cookie = UserDefaults.standard.string(forKey: "JSESSIONID")
    if cookie == nil {
        return Future<Any, Error> { promise in
            promise(.failure(BremerConnectionError()))
        }.eraseToAnyPublisher()
    }
    var request:URLRequest = URLRequest(url: url)
    request.httpMethod = httpMethod
    request.setValue("JSESSIONID=\(cookie!)", forHTTPHeaderField: "Cookie")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    do {
        let jsonEncoder = JSONEncoder()
        jsonEncoder.keyEncodingStrategy = .convertToSnakeCase
        request.httpBody = try jsonEncoder.encode(requestBody)
    } catch {
        // TODO あとで例外書く
        print("エラー")
    }
    let jsonDecoder = JSONDecoder()
    jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase
    return URLSession.shared.dataTaskPublisher(for: request)
        .tryMap { res in
            guard let httpResponse = res.response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
                throw BremerConnectionError()
            }
            return res
        }
        .receive(on: DispatchQueue.main)
        .eraseToAnyPublisher()
}