frenzy-ios/Fervor/FervorClient.swift

89 lines
2.8 KiB
Swift

//
// FervorClient.swift
// Fervor
//
// Created by Shadowfacts on 11/25/21.
//
import Foundation
public class FervorClient {
let instanceURL: URL
let session: URLSession
public var accessToken: String?
private let decoder: JSONDecoder = {
let d = JSONDecoder()
d.dateDecodingStrategy = .iso8601
return d
}()
public init(instanceURL: URL, accessToken: String?, session: URLSession = .shared) {
self.instanceURL = instanceURL
self.accessToken = accessToken
self.session = session
}
private func buildURL(path: String) -> URL {
var components = URLComponents(url: instanceURL, resolvingAgainstBaseURL: false)!
components.path = path
return components.url!
}
private func performRequest<T: Decodable>(_ request: URLRequest) async throws -> T {
var request = request
if let accessToken = accessToken {
request.addValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
}
let (data, _) = try await session.data(for: request, delegate: nil)
let decoded = try decoder.decode(T.self, from: data)
return decoded
}
public func register(clientName: String, website: URL? = nil, redirectURI: URL) async throws -> ClientRegistration {
var request = URLRequest(url: buildURL(path: "/api/v1/register"))
request.httpMethod = "POST"
request.setURLEncodedBody(params: [
"client_name": clientName,
"website": website?.absoluteString,
"redirect_uri": redirectURI.absoluteString,
])
return try await performRequest(request)
}
public func token(authCode: String, redirectURI: URL, clientID: String, clientSecret: String) async throws -> Token {
var request = URLRequest(url: buildURL(path: "/oauth/token"))
request.httpMethod = "POST"
request.setURLEncodedBody(params: [
"grant_type": "authorization_code",
"authorization_code": authCode,
"redirect_uri": redirectURI.absoluteString,
"client_id": clientID,
"client_secret": clientSecret,
])
return try await performRequest(request)
}
public func groups() async throws -> [Group] {
let request = URLRequest(url: buildURL(path: "/api/v1/groups"))
return try await performRequest(request)
}
public func feeds() async throws -> [Feed] {
let request = URLRequest(url: buildURL(path: "/api/v1/feeds"))
return try await performRequest(request)
}
public struct Auth {
public let accessToken: String
public let refreshToken: String?
}
public enum Error: Swift.Error {
case urlSession(Swift.Error)
case decode(Swift.Error)
}
}