Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Expose fields from BoxResponse for custom API calls #833

Merged
merged 1 commit into from
Apr 13, 2022
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
14 changes: 13 additions & 1 deletion Sources/Core/Extensions/URLExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@

import Foundation

extension URL {
public extension URL {

/// Creates a valid `URL` based on configuration's `apiBaseURL` and `endpoint` path
///
/// - Parameters:
/// - endpoint: The relative path that will be appended to `apiBaseURL`
/// - configuration: The SDK configuration that provides `apiBaseURL` URL
/// - Returns: The URL of the API endpoint.
static func boxAPIEndpoint(_ endpoint: String, configuration: BoxSDKConfiguration) -> URL {
return URL.make(from: endpoint, relativeTo: configuration.apiBaseURL)
}

/// Creates a valid `URL` based on configuration's `uploadApiBaseURL` and `endpoint` path
///
/// - Parameters:
/// - endpoint: The relative path that will be appended to `uploadApiBaseURL`
/// - configuration: The SDK configuration that provides `uploadApiBaseURL` URL
/// - Returns: The URL of the upload API endpoint.
static func boxUploadEndpoint(_ endpoint: String, configuration: BoxSDKConfiguration) -> URL {
return URL.make(from: endpoint, relativeTo: configuration.uploadApiBaseURL)
}
Expand Down
10 changes: 5 additions & 5 deletions Sources/Core/ResponseHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
import Foundation

/// Utility methods for common response handling
enum ResponseHandler {
public enum ResponseHandler {

/// Make sure the response is successful (status code 2xx) and deserialize
/// the response body into the appropriate type.
///
/// - Parameter completion: The user-specified completion block to call with the resulting deserialized object
static func `default`<T: BoxModel>(wrapping completion: @escaping Callback<T>) -> Callback<BoxResponse> {
public static func `default`<T: BoxModel>(wrapping completion: @escaping Callback<T>) -> Callback<BoxResponse> {
return { (result: Result<BoxResponse, BoxSDKError>) in
let objectResult: Result<T, BoxSDKError> = result.flatMap { ObjectDeserializer.deserialize(data: $0.body) }
completion(objectResult)
Expand All @@ -26,7 +26,7 @@ enum ResponseHandler {
/// the response body into the appropriate type.
///
/// - Parameter completion: The user-specified completion block to call with the resulting deserialized object
static func `default`<T: Decodable>(wrapping completion: @escaping Callback<T>) -> Callback<BoxResponse> {
public static func `default`<T: Decodable>(wrapping completion: @escaping Callback<T>) -> Callback<BoxResponse> {
return { (result: Result<BoxResponse, BoxSDKError>) in
let objectResult: Result<T, BoxSDKError> = result.flatMap { ObjectDeserializer.deserialize(response: $0) }
completion(objectResult)
Expand All @@ -37,7 +37,7 @@ enum ResponseHandler {
/// for operations that do not return meaningful results — just success vs. failure.
///
/// - Parameter completion: The user-specified completion block to call with the result
static func `default`(wrapping completion: @escaping Callback<Void>) -> Callback<BoxResponse> {
public static func `default`(wrapping completion: @escaping Callback<Void>) -> Callback<BoxResponse> {
return { (result: Result<BoxResponse, BoxSDKError>) in
let objectResult = result.map { _ in }
completion(objectResult)
Expand All @@ -47,7 +47,7 @@ enum ResponseHandler {
/// This will help the user unwrap a response object that comes back as a collection where the collection
/// is only of size one. This will give the user an Entry Container containing the Box Model expected.
/// - Parameter completion: The user-specified completion block to call with the result
static func unwrapCollection<T: BoxModel>(wrapping completion: @escaping Callback<T>) -> Callback<BoxResponse> {
public static func unwrapCollection<T: BoxModel>(wrapping completion: @escaping Callback<T>) -> Callback<BoxResponse> {
return { result in
completion(result.flatMap {
ObjectDeserializer.deserialize(data: $0.body).flatMap { (container: EntryContainer<T>) in
Expand Down
19 changes: 16 additions & 3 deletions Sources/Network/ObjectDeserializer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@

import Foundation

enum ObjectDeserializer {
/// Provides methods for deserialization JSON data to custom objects
public enum ObjectDeserializer {

static func deserialize<ReturnType: BoxModel>(data: Data?) -> Result<ReturnType, BoxSDKError> {
/// Deserializes `Data?` object to the type that conforms to `BoxModel` and returns a `Result` of this type if success
/// or `BoxSDKError` on failure.
///
/// - Parameters:
/// - data: Binary data to deserialize
/// - Returns: Returns an object if success otherwise error
public static func deserialize<ReturnType: BoxModel>(data: Data?) -> Result<ReturnType, BoxSDKError> {

guard let bodyData = data else {
return .failure(BoxCodingError(message: "Invalid response to deserialize"))
Expand All @@ -33,7 +40,13 @@ enum ObjectDeserializer {
}
}

static func deserialize<ReturnType: Decodable>(response: BoxResponse) -> Result<ReturnType, BoxSDKError> {
/// Deserializes `BoxResponse` object to the type that conforms to `Decodable` and returns a `Result` of this type if success
/// or `BoxSDKError` on failure.
///
/// - Parameters:
/// - response: The `BoxResponse` object which `body` will be deserialize
/// - Returns: Returns an object if success otherwise error
public static func deserialize<ReturnType: Decodable>(response: BoxResponse) -> Result<ReturnType, BoxSDKError> {

guard let bodyData = response.body else {
return .failure(BoxCodingError(message: "Invalid response to deserialize"))
Expand Down
12 changes: 8 additions & 4 deletions Sources/Responses/BoxResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@

import Foundation

/// Box API request response
/// Box API response
public struct BoxResponse {
var request: BoxRequest
var body: Data?
var urlResponse: HTTPURLResponse?
/// The Box SDK API request related to this response.
public let request: BoxRequest
/// The body of the response in a binary format
public let body: Data?
/// The object that represents a HTTP response which includes data such as
/// `statusCode` or `allHeaderFields`
public let urlResponse: HTTPURLResponse?

init(request: BoxRequest, body: Data?, urlResponse: URLResponse?) {
self.request = request
Expand Down